うまくまとまらないけど、つらつら書いてみようと思う。
vaskir's blog: Hash maps: Rust, F#, D, Go, Scala
読んでてScalaの数値があんまり良くない原因がコメント欄で書かれてた
Scala/JVM's boxing and unboxing is very slow in such a tight loop.
Eclipse collections may be useful.
https://gist.github.com/zakki/66d785b4a9d3c64bc9f8199d7e290e07 13x faster
ただ、元コードがRustでの
- std::collections::{HashMap}へのキー追加
- Vecで頭から参照しながら足してく
なので、int[]で計算してたのが気になったのでeclipseコレクションつかって計算してみた
- org.eclipse.collections.impl.factory.primitive.IntIntMaps
- org.eclipse.collections.impl.factory.primitive.IntLists
import org.eclipse.collections.api.list.primitive.MutableIntList;
import org.eclipse.collections.impl.factory.primitive.IntIntMaps;
import org.eclipse.collections.impl.factory.primitive.IntLists;
import java.util.Random;
import java.util.function.Supplier;
import java.util.stream.IntStream;
public class Main {
private static <T> void time(final String name, Supplier<T> func) {
long s = System.nanoTime();
func.get();
System.out.println(String.format("%s: %d elapsed.", name, (System.nanoTime() - s) / 1_000_000));
}
public static void main(String[] args) {
final MutableIntList source = IntLists.mutable.empty();
final Random r = new Random();
IntStream.range(0, 50_000_000).forEach(i -> source.add(r.nextInt()));
time("Insertion", () -> source.injectInto(IntIntMaps.mutable.empty(), (x, y) -> {
x.put(y, 0);
return x;
}));
time("Lookups", () -> source.injectInto(0, (x, y) -> x + (y % 10)));
}
}
https://gist.githubusercontent.com/masahitojp/475f8da57fd54f56bf9d7786c1311f6a/raw/d9f208ea1c9e29d6b644fbdf38f41d4014074a5b/ECMain.java
それにしてもMapは遅いなぁ。。。
// Map
Insertion : 42535 elapsed.
// eclipse collectionを使用
Insertion: 1040 elapsed.
まとめ
boxing/unboxingがきになるときはEclipese Collectionを積極的につかうべし