Reviewing code, I came across a number of new Private Shared variables (of type Hashtables(Of String), initialized in the declaration) added to a partial class for a very large (DataContext-derived) class. This seems sensible to me in one sense because they never change, and making these shared variables ensures that they won't get re-initialized every time a function is called. However, these variables are only used within the scope of one function in the class, and I fear the private namespace of this DataContext-derived class is getting rather polluted, and having these sorts of things exposed at such a high level might be confusing to others reading the code in the future. Would there be negative performance impact to making these local variables within the function where they are used, or is there some better way to handle this? Basically we are using these 3 hashtables to determine whether anything within particular subsets of properties changed (using GetModifiedMembers and then using the Overlaps function of the hashset to see if any of the modified members correspond to members we care about).
Edit: I caved and took the time to write my own test program, which confirmed that there is a cost to using local variables (which I assume applies generally to all cases -- I doubt there's any case where a shared variable would be slower unless using the shared variable requires some additional logic to do so properly):
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
Sample Output:
Shared: 75232
00:00:00.0408223
Local: 75018
00:00:00.1344628
So in this particular case, using the local variable costs about 200%. But in most cases (including my own), the time is probably negligible compared to the overall task. So I guess the question now becomes, how do people generally feel about improving code maintainability at the cost of negligible but known performance impacts?