I've create a PR for a templated opEquals here
(https://github.com/D-Programming-Language/druntime/pull/1087).
Currently it will not build without some changes in phobos, PR
here
(https://github.com/D-Programming-Language/phobos/pull/2848).
Using the new templated opEquals it fixed the
overhead/performance issues as seen here:
compiled on windows(x64): dmd opEqualsTest.d -inline -O -release
run 1 (loopcount 10000000)
x.x == y.x : 11609 microseconds
x.opEquals(y) : 22303 microseconds
x.opEquals(cast(Object)y): 146859 microseconds
x == y : 37685 microseconds
run 2 (loopcount 10000000)
x.x == y.x : 7525 microseconds
x.opEquals(y) : 7528 microseconds
x.opEquals(cast(Object)y): 106771 microseconds
x == y : 37251 microseconds
As you can see the '==' operator is now much close to the direct
call to opEquals. There is still some minimal overhead (I think
caused by an extra function call and some null checks) but it is
much closer. I'm still working on the PRs but this may be a good
solution.