Hash maps: Rust, F#, D, Go, Scala
Let's compare performance of hashmap implementation in Rust, .NET, D (LDC) and Go.
Rust:
F#:
As you can see, Rust is slower at about 17% on insersions and at about 21% on lookups.
Yes, it's significantly faster: additions is only 5% slower than .NET implementation, and lookups are 32% *faster*! Great.
It's very slow at insertions and quite fast on lookups.
Compared to Scala all the other languages looks equally fast :) What's worse, Scala loaded all four CPU cores at almost 100% during the test, while others used roughly single core. My guess is that JVM allocated so many objects (each Int is an object, BTW), that 3/4 of CPU time was spend for garbage collecting. However, I'm a Scala/JVM noob, so I just could write the whole benchmark in a wrong way. Scala developers, please review the code and explain why it's so slow (full IDEA/SBT project is here). Thanks!
Rust:
F#:
As you can see, Rust is slower at about 17% on insersions and at about 21% on lookups.
Update
As @GolDDranks suggested on Twitter, since Rust 1.7 it's possible to use custom hashers in HashMap. Let's try it:Yes, it's significantly faster: additions is only 5% slower than .NET implementation, and lookups are 32% *faster*! Great.
Update: D added
LDC x64 on windowsIt's very slow at insertions and quite fast on lookups.
Update: Go added
Update: Scala added
Compared to Scala all the other languages looks equally fast :) What's worse, Scala loaded all four CPU cores at almost 100% during the test, while others used roughly single core. My guess is that JVM allocated so many objects (each Int is an object, BTW), that 3/4 of CPU time was spend for garbage collecting. However, I'm a Scala/JVM noob, so I just could write the whole benchmark in a wrong way. Scala developers, please review the code and explain why it's so slow (full IDEA/SBT project is here). Thanks!
Comments
----
elapsed = stopTime!({
auto acc = 0;
foreach(i; 0 .. 50_000_000)
acc += m[i] % 10;
}) ;
----
Also in D you seem to repeat twice the operations because of the additional
----
auto _ = m[x];
----
Which is not done in the other languages. So finally I think that's it's unfair.
What you really should do in D is
----
elapsed = stopTime!({
auto acc = 0;
foreach(x; source) {
if (auto v = x in m)
acc += *v % 10;
}
})
----
And you'll see the lookup time reduced by 65 to 75 %.
Eclipse collections may be useful.
https://gist.github.com/zakki/66d785b4a9d3c64bc9f8199d7e290e07 13x faster