kagamihogeの日記

kagamihogeの日記です。

javaのinitialCapacityの速度差

javaHashMapなどはコンストラクタでinitialCapacityで指定できる。単純ループでputしたとき速度差が生じるかを見る。

環境

やったこと

まず、ごく単純なループで固定文字列を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は指定無しで問題無さそう。初期値は優秀という事でもあろう。あとは、マシンスペックにも依存するのでやはり計測してみないことには何とも言え無さそうである。