I am writting a thread safe object that basically represents a double and uses a lock to ensure safe reading and writing. I use many of these objects (20-30) in a piece of code that is reading and writing them all 100 times per second, and I am measuring the average computation time of each of these time steps. I started looking at a few options for implementations of my getter and after running many tests and collecting many samples to average out my measurement of computation time I find certain implementations perform consistently better than others, but not the implementations I would expect.
Implementation 1) Computation time average = 0.607ms:
protected override double GetValue()
{
lock(_sync)
{
return _value;
}
}
Implementation 2) Computation time average = 0.615ms:
protected override double GetValue()
{
double result;
lock(_sync)
{
result = _value;
}
return result;
}
Implementation 3) Computation time average = 0.560ms:
protected override double GetValue()
{
double result = 0;
lock(_sync)
{
result = _value;
}
return result;
}
What I expected: I had expected to see implementation 3 be the worst of the 3 (this was actually my original code, so it was chance or lazy coding that I had written it this way), but surprisingly it is consistently the best in terms of performance. I would expect implementation 1 to be the fastest. I also expected implementation 2 to be at least as fast, if not faster than implementation 3 since I am just removing an assignment to the double result that is overwritten anyways, so it is unnecessary.
My question is: can anyone explain why these 3 implementations have the relative performance that I have measured? It seems counter-intuitive to me and I would really like to know why.
I realize that these differences are not major, but their relative measure is consistent every time I run the test, collecting thousands of samples each test to average out the computation time. Also, please keep in mind I am doing these tests because my application requires very high performance, or at least as good as I can reasonably get it. My test case is just a small test case and a my code's performance will be important when running in release.
EDIT: note that I am using MonoTouch and running the code on an iPad Mini device, so perhaps it's nothing related to c# and more something related to MonoTouch's cross compiler.