Bei der Überprüfung des Codes stieß ich auf eine Reihe neuer Private Shared-Variablen (vom Typ Hashtables (Of String), initialisiert in der Deklaration), die zu einer partiellen Klasse für eine sehr große (DataContext-abgeleitete) Klasse hinzugefügt wurden. Dies erscheint mir in einem Sinn sinnvoll, weil sie sich niemals ändern und diese geteilten Variablen sicherstellen, dass sie nicht jedes Mal neu initialisiert werden, wenn eine Funktion aufgerufen wird. Diese Variablen sind nur innerhalb des Bereichs einer Funktion in der Klasse verwendet, und ich fürchte, der private Namespace dieser DataContext-abgeleiteten Klasse wird ziemlich verschmutzt, und diese Dinge auf einem so hohen Niveau ausgesetzt sein könnte verwirrend für andere, die den Code in der Zukunft lesen. Würde es negative Auswirkungen auf die Leistung haben, diese lokalen Variablen in der Funktion zu verwenden, in der sie verwendet werden, oder gibt es einen besseren Weg, damit umzugehen? Im Grunde verwenden wir diese 3 Hashtabellen, um zu bestimmen, ob sich irgendetwas innerhalb bestimmter Teilmengen von Eigenschaften geändert hat (mit GetModifiedMembers und dann mit der Overlaps-Funktion des Hashsets, um festzustellen, ob eines der modifizierten Mitglieder den Mitgliedern entspricht, die uns interessieren).Private Shared-Variablen im Vergleich zu lokalen Variablen/Namespace Pollution vs Performance?
Edit: Ich gab nach und nahm mir die Zeit, um mein eigenes Testprogramm zu schreiben, das bestätigte, dass es Kosten für die Verwendung von lokalen Variablen gibt (was ich generell für alle Fälle anwende). Ich bezweifle, dass es einen Fall gibt Variable langsamer sein würde, es sei denn, die gemeinsame Variable einige zusätzliche Logik erfordert, so richtig zu machen):
Sub Main()
Dim st As New Stopwatch()
Dim specialCount As Integer = 0
Dim r As New Random()
Dim params As Integer()
ReDim params(0 To 9)
st.Start()
For i As Integer = 1 To 100000
For j As Integer = 0 To 9
params(j) = r.Next(100)
Next
If IsSpecialShare(params) Then specialCount += 1
Next
st.Stop()
Console.WriteLine("Shared: " & specialCount)
Console.WriteLine(st.Elapsed.ToString())
st.Reset()
specialCount = 0
st.Start()
For i As Integer = 1 To 100000
For j As Integer = 0 To 9
params(j) = r.Next(100)
Next
If IsSpecialLocal(params) Then specialCount += 1
Next
st.Stop()
Console.WriteLine("Local: " & specialCount)
Console.WriteLine(st.Elapsed.ToString())
End Sub
Dim specialListShared As New HashSet(Of Integer)(New Integer() {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41})
Private Function IsSpecialLocal(ByVal paramList As IEnumerable(Of Integer)) As Boolean
Dim specialListLocal As New HashSet(Of Integer)(New Integer() {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41})
Return specialListLocal.Overlaps(paramList)
End Function
Private Function IsSpecialShare(ByVal paramList As IEnumerable(Of Integer)) As Boolean
Return specialListShared.Overlaps(paramList)
End Function
Beispielausgabe:
Shared: 75232
00:00:00.0408223
Local: 75018
00:00:00.1344628
so in diesem speziellen Fall die lokale Variable kostet etwa 200% . Aber in den meisten Fällen (einschließlich meiner eigenen) ist die Zeit im Vergleich zur Gesamtaufgabe wahrscheinlich vernachlässigbar. Ich denke also, die Frage wird nun, wie fühlen sich die Menschen im Allgemeinen dazu, die Wartbarkeit des Codes auf Kosten von vernachlässigbaren, aber bekannten Leistungseinbußen zu verbessern?
Ich glaube nicht, ich bin besorgt über tatsächliche messbare Leistung hier, da der Unterschied wahrscheinlich nicht nachweisbar klein wäre. Und es gibt leistungsorientierte Richtlinien da draußen, unabhängig von der Notwendigkeit, einzelne Fälle zu profilieren. Genau darum geht es mir hier. Zum Beispiel sollten Sie in der Regel stark typisierte Variablen anstelle von Objektreferenzen verwenden, um mit Werttypen umzugehen, wo dies aufgrund der Kosten für das Boxing und das Un-Boxing möglich ist. Meine ähnliche Frage lautet, ob bei der Verwendung lokaler Variablen statt gemeinsamer Variablen erhebliche Kosten zu berücksichtigen sind. Nutzen/Kosten? – BlueMonkMN
Eigentlich ist es eine Konstante, aber (obwohl VB.NET lokale Konstanten erlaubt) ist es nicht möglich, eine Konstante mit dieser Art von Wert zu deklarieren, also müssen wir eine Variable deklarieren. Und dann stoßen wir auf eine ähnliche Frage: Sind die Kosten des Overheads, die zusätzlichen Instanzen zu haben, den Vorteil, den Namensraum der Klasse zu entlasten? Es ist wirklich eine Konstante, die nur auf diese spezifische Funktion anwendbar ist. Es ist nur eine Liste von Eigenschaftsnamen für Eigenschaften, deren Werte innerhalb dieser Funktion behandelt werden. – BlueMonkMN
Dann würde ich es als statische lokale Variable deklarieren. Der Overhead ist wahrscheinlich sehr klein, daher lohnt es sich, den Namensraum der Klasse zu entlasten, es sei denn, es gibt Millionen von Objekten dieses Typs, die erstellt werden. (1 Million Objekte = 1 Million Kopien Ihrer statischen Variablen) –