Why is test4 and test6 much slower than their delegate version? I also noticed that Resharper specifically comments on the delegate version, proposing to change test5 and test7 to "Covert to method group". What is the same as test4 and test6, but are they actually slower?
You will get a big key by adding
Debug.Print(ReferenceEquals(list[0], list[1]) ? "same" : "different");
to the end of each method.
With the delegate version, Func gets the compiled bit, as it actually was:
var func = Func<CacheDependency> <>_hiddenfieldwithinvalidC#name; if (func == null) { <>_hiddenfieldwithinvalidC#name = func = () => p.GetDep(); }
While in the group of methods it compiles in the same way as:
func = new Func<CacheDependency>(p.GetDep());
This memory has been done a lot with delegates created from lambdas, when the compiler can determine that it is safe, but not with groups of methods that are passed to delegates, and the performance differences that you see show exactly why.
I don't seem to agree with the performance difference when calling test4 and test6, aren't static calls always faster?
Not necessary. While a static call has the advantage of one smaller argument to pass through (since there is no implicit this argument), this difference:
- Itβs not worth starting.
- May be disabled if
this not used. - It can be optimized that the register with the
this pointer before the call is the register with the this pointer after the call, so there is no need to actually do anything to get it. - Uh, something else. I am not saying that this list is exhaustive.
Indeed, the performance benefits of statics are more if you do things that are naturally static in instance methods, you may end up skipping objects that are really unnecessary and waste time. However, if you do what is a natural instance in static methods, you can end up storing / retrieving and / or distributing g and / or passing objects in arguments that you don't need and will be just as bad.