Computing cryptography hashes: Rust, F#, D and Scala
Let's compare how fast Rust, D and F# (.NET actually) at computing cryptography hashes, namely MD5, SHA1, SHA256 and SHA512. We're going to use rust-crypto cargo:
Results:
Now the F# code:
Results:
- MD5 - 3.39s
- SHA1 - 2.89s
- SHA256 - 6.97s
- SHA512 - 4.47s
Now the F# code:
Results (.NET 4.5, VS 2013, F# 3.1):
DMD
LDC2
- MD5CryptoServiceProvider - 2.32s (32% faster)
- SHA1CryptoServiceProvider - 2.92s (1% slower)
- SHA256Managed - 16.50s (236% slower)
- SHA256CryptoServiceProvider - 11.50s (164% slower)
- SHA256Cng - 11.71s (168% slower)
- SHA512Managed - 61.04s (1365% slower)
- SHA512CryptoServiceProvider - 21.88s (489% slower)
- SHA512Cng - 22.19s (496% slower)
(.NET 4.6, VS 2015, F# 4.0):
D:
- MD5CryptoServiceProvider elapled 2.55
- SHA1CryptoServiceProvider elapled 2.89
- SHA256Managed elapled 17.01
- SHA256CryptoServiceProvider elapled 8.74
- SHA256Cng elapled 8.75
- SHA512Managed elapled 23.42
- SHA512CryptoServiceProvider 5.81
- SHA512Cng elapled 5.79
D:
- MD5 - 16.05s (470% slower)
- SHA1 - 2.35s (19% faster)
- SHA256 - 47.96s (690% slower (!))
- SHA512 - 61.47s (1375% slower (!))
- MD5 - 2,18s (55% faster)
- SHA1 - 2.88s (same)
- SHA256 - 6,79s (3% faster)
- SHA512 - 4,6s (3% slower)
GDC
Scala:
Interesting things:
- MD5 - 2,43 (29% faster)
- SHA1 - 2,84 (2% faster)
- SHA256 - 12,62 (45% slower)
- SHA512 - 8,56 (48% slower)
Scala:
- MD5 - 4.2s (23% slower)
- SHA1 - 6.09s (110% slower)
- SHA256 - 9.96s (42% slower)
- SHA512 - 7.32s (63% slower)
- Rust and D (LDC2) show very close results. D is significantly faster on MD5, so it's the winner!
- D (DMD) has very bad performance on all algorithms, except SHA1, where it's won.
- SHA512Managed .NET class is very slow. Do not use it.
Comments
bench (new SHA256CryptoServiceProvider()) input
bench (new SHA512CryptoServiceProvider()) input
It probably works only on Windows, but it gives a huge performance improvement (nearly on par with rust).
So some D users use gdc(gcc)/ldc(llvm) for such cases, e.g. cryptography, machine learning, statistics and etc.
I tested your code and dmd / ldc results on my MBP are below:
dmd 2.067:
MD5 - 8363 ms elapsed.
SHA1 - 16611 ms elapsed.
SHA256 - 35451 ms elapsed.
SHA512 - 24743 ms elapsed.
ldc2-0.15.2-beta1:
MD5 - 1970 ms elapsed.
SHA1 - 1676 ms elapsed.
SHA256 - 4273 ms elapsed.
SHA512 - 2964 ms elapsed.
ldc's performance is quite similar to Rust :)
using LDC for D I had D come out faster in all four.
Could you please retry with LDC? dmd is just a reference implementation(ala cpython) with a very old, poorly optimizing backend based on Zortech/Digital Mars C++.
Suggested flags:
ldc -O5 -release
Bye,
d:\ldc2-0.15.2-beta1-win64-msvc\bin\ldc2.exe -O5 -release main.d
OPTLINK (R) for Win32 Release 8.00.17
Copyright (C) Digital Mars 1989-2013 All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
OPTLINK : Warning 9: Unknown Option : NXCOMPAT
OPTLINK : Warning 9: Unknown Option : DYNAMICBASE
OPTLINK : Warning 9: Unknown Option : OUT
OPTLINK : Error 8: Illegal Filename
/NOLOGO /NXCOMPAT /DYNAMICBASE /LARGEADDRESSAWARE /OPT:REF /OPT:ICF /OUT:main.exe main.obj "/LIBPATH
:d:\ldc2-0.15.2-beta1-win64-msvc\bin/../lib" phobos2-ldc.lib druntime-ldc.lib kernel32.lib user32.li
b gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
^
Error: d:\DMD\dmd2\windows\bin\link.exe failed with status: 1
__________________________
What am I doing wrong?
Looks like after the LDC inclusion, D wins 3 out of 4 times.
It would be interesting to see Bouncy Castle for both .NET and JVM implementations.
Read more