It’s quite common that I need a property in my class which needs to be calculated and cached.
Generally I use a lock and a boolean top check if it’s processed or not. Sometimes I do it in accessors.
What’s the performance hit of this approach? Is there any better way to it.
Sample Code of my common approach to this:
Sub Main()
Dim X AS New X()
For i AS Integer = 0 To 50
Dim Thr AS New Threading.Thread(ADdressOF X.ProcessData )
Thr.Start()
Next
End Sub
Private Class X
Private DataCached AS Boolean
Private ProcessedData AS String
Private Lock AS New Object()
Public Function ProcessData() AS String
Synclock Lock
IF NOT DataCached Then
DataCached = True
ProcessedData = DoStuff()
End If
End Synclock
Console.Writeline(ProcessedData)
Return ProcessedData
End Function
Function DoStuff() AS String
Threading.Thread.Sleep(1000)
Console.Writeline("Processed")
return "stuff"
End Function
End Class
EDIT :
This is something that need to be calculated when accessed because it keeps changing. Constructor calculation doesn’t help in here. (sample is a really simplified version of what I’m doing)
Is it critical that it is never calculated twice? i.e. if two threads happened to ask for it at the same time, and calculate the value independently, is that a show-stopper? In most cases, it isn’t – in which case, just check for
null(since it is a string): (example in C#, apologies):All subsequent calls should see the new value (I don’t think we’ll need
volatileif it is hidden inside a property/method).This has the advantage of being lock-free and simple.
Another trick is to use a static property of a nested class:
This is calculated lazily, but the rules of static initializers mean that it is guaranteed to run once only (excluding reflection).