MD5 Optimizations for C#
OMG, I just spent an entire day optimizing - or trying - the MD5 algorithm for C#. Especially since the one shipped with mono right now is slooooooow when all optimizations are enabled (yeah, go figure.
). Now I am frustrated, because optimizing is such a hassle, especially when it involves JIT... Well, the code is now quite a bit faster than the default implementation MD5CryptoServiceProvider. (About 40%) But here is one of the many things that are a bit weird. The MD5-Algo has a step that looks like
- a += ((b & c) | (~b & d)) + _decodeBuf0 + (int)0xd76aa478;
which can be translated into
- a += (d ^ (b & (c ^ d))) + _decodeBuf0 + (int)0xd76aa478;
This actually does increase the speed of the Transform step. But in Microsoft's .NET, using the SAME optimization 10 lines further down is decreasing performance! Why, oh, why?
Well, at least mono is well behaved. On the other hand, mono is actually quite surprising, too: It performs best, when there is no Unsafe code involved! Even the highest optimized version, using pointers and all kinds of tricks in unsafe mode is about 5% slower than the safe version!
But here is the problem: Now I have like 10 different types of optimizations. Which are all optimal for a specific framework, platform and/or hardware. (yeah, I tested on several different machines) Btw.: Arrays are extremely slow in Microsoft's .NET, but quite fast in Mono... So, what's the solution to my problem? What we need is a library that has like a calibration routine that will choose the right code. ![]()
I'll probably post the code of the optimized code, the framework to choose the right optimization and the Testprograms in a couple of days.
Conclusion:
Once again it became clear that there is no such thing as THE optimization.
For the purists (and my source for the implementation - minus the Appendix):
The MD5 RFC 1321

Hi Tobi,
what do you mean, arrays are not very optimized? When do you release the sourcecode.
Cheers,
MarcC
Comment on April 29, 2006 @ 23:44:20
Hi Marc,
thanks for your comment. What I meant by that is that it is way faster to split an array, which length is fixed, into several variables. E.g. the MD5-Algorithm uses a decoding buffer that is 16 ints wide. So instead of using int[16] I used 16 separate int variables and that optimization produced quite a performance boost.
Have a good one,
T
Comment on May 1, 2006 @ 10:51:53
Why don’t you send your findings and your code to the mono team so they can reimplement the MD5CryptoServiceProvider?
Comment on June 7, 2006 @ 13:20:28
Hi John,
I have already been looking at the code and tried to implement some of my findings. But unfortunatelly other projects took a lot of my time. So I did not have the time yet to implement a complete MD5CryptoServiceProvider. But I guess I will try and find out whom to contact of the mono team.
Thank you for the input.
Cheers,
Tobi
Comment on June 7, 2006 @ 17:44:44
[...] Inspired by a comment here, I implemented a couple of my optimization strategies as MD5CryptoServiceProvider. Tests are running as I speak and should be done tomorrow morning, but these figures sure do give some hope: [...]
Pingback on June 9, 2006 @ 01:20:48
mono sucks because those who write code for free, don’t have any reservations from writing garbage code that gets them fired.
Comment on May 26, 2008 @ 22:39:04
You are certainly entitled to have that opinion – which does not mean that I share your concern.
what I found though is that open source code is usually written by someone who loves to solve that particular problem – and not someone who is paid to do so. better or worse?
Apart from that – I noticed you wrote that comment using Firefox.
Comment on May 27, 2008 @ 10:00:41