Is there extra overhead in using the object.ReferenceEquals method verses using ((object)obj1 == (object)obj2)?
In the first case, there wo
Adding my two cents, after many late hours in perf critical code, on very large codebases with sometimes crazy deep call depths.
Outside a 'micro benchmark' in the real world, the JIT has many more problems and concerns, and niether has the luxry of the compile time C++ WPO, nor the ease of the C# compilers more direct translations, and yet all the problems of not nessesarily having all the context after C# compiler is done.
The 'pedantic' forms:
if ((object)a == (object)b) { } // ref equals
if (!((object)a == (object)b)) { } // ref not equals
If you really have honest-to-god perf issues weighed and mesured, or need to take pressure off the JIT for a few really big pervasive classes, this can help a ton. Same is true with NullOrEmpty vs '(object)str == null || str.Length == 0' .
Not having the luxury of WPO, and all the contraints of not knowing in many cases, what assemblies may get loaded or unloaded after its taken a whack at JITing, odd non-deterministic things happen with respect to what gets optimized and how.
This is a huge topic, but here are a few points:
The JIT will chase inlining and register optimzation a down call depth only so far, and totally depends on what else is going on at the time. If you end up compiling a function up the chain one time due to use, and one farther down the chain a different run, you can get drastically differnet results. The worst thing for many applications that are either bound by latency or UI driven is non-depterminism, and in larger apps this can add up quickly.
!((object)a == (object)b) and (object)a != (object)b are not always compiled down to the same code, as is true certianly for !(a == b) and a != b, even without any explicit operators or Equals overrides. A '(object)a != (object)b' is far more likely to trigger .Net's own more pedantic call down into the runtime which is very expensive.
Guarding early and often with '(object)' or 'RefEquals' if very helpful to the JIT even if you currently dont have operator or Equals overrides. (object) is even better. If you think about what the JIT has to do to detemine if a type could have overrides, and deal with the bizantine (sp) Equality rules and whatnot, its like a mini hell, and anyting that could be made public later and you intend ref equality you save yourself from a sudden slowdown or wonky code later. If its already is public and not sealed, the JIT cant quarentee that the rules will or have time to chase them down.
Guarding the generally more pervasive 'null' checks is probaly even more important, though not a part of the OP's question, as the same rules and issues generally apply. '(object)a == null' and '!((object)a == null)' being the 'pedantic' equivalents.