うまくまとまらないけど、つらつら書いてみようと思う。
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))); } // Insertion: 4793 elapsed. // Lookups: 482 elapsed. }
それにしてもMap
// Map
Insertion : 42535 elapsed.
// eclipse collectionを使用
Insertion: 1040 elapsed.
まとめ
boxing/unboxingがきになるときはEclipese Collectionを積極的につかうべし