javaのHashMap
などはコンストラクタでinitialCapacity
で指定できる。単純ループでput
したとき速度差が生じるかを見る。
環境
- java 17.0.1
やったこと
まず、ごく単純なループで固定文字列をput
し続け、maxを100万と1000万と変えたときの速度を見てみる。
static int max = 10_000_000; private static void hoge1() { long start = System.currentTimeMillis(); // Map<Integer, String> map = new HashMap<>(max); Map<Integer, String> map = new HashMap<>(); for (int i=0; i<max; i++) { map.put(i, "0123456789012345"); } System.out.println(System.currentTimeMillis() - start); }
以下が測定結果で上が100万で下が1000万、ありがinitialCapacity
を指定あり。
1 | 2 | 3 | |
---|---|---|---|
なし | 101 | 97 | 105 |
あり | 101 | 97 | 114 |
1 | 2 | 3 | |
---|---|---|---|
なし | 700 | 706 | 709 |
あり | 514 | 510 | 514 |
100万だと差は無いが1000万だと僅かに速くなっている。
次に、ループ内の処理を複雑にしてみる。具体的には以下のようにvalueをランダム文字列生成に変えてみる。
private static void hoge2() { RandomStringGenerator generator = new RandomStringGenerator.Builder() .build(); long start = System.currentTimeMillis(); // Map<Integer, String> map = new HashMap<>(max); Map<Integer, String> map = new HashMap<>(); for (int i=0; i<max; i++) { map.put(i, generator.generate(16)); } System.out.println(System.currentTimeMillis() - start); }
1 | 2 | 3 | |
---|---|---|---|
なし | 33055 | 32992 | 33054 |
あり | 33275 | 33040 | 32687 |
ほとんど差が無くなった。ループ内で重い処理があるとinitialCapacity
で稼いだ分も誤差の範囲内に入ってしまうようだ。
感想とか
億単位まで件数を増やしてループ内の処理をあれこれ考慮しないと意味のある知見は得られなさそうである。ただ、少なくとも1000万くらいまでならinitialCapacity
は指定無しで問題無さそう。初期値は優秀という事でもあろう。あとは、マシンスペックにも依存するのでやはり計測してみないことには何とも言え無さそうである。