動的配列の領域確保は事前に行うと速い

VBAの動的配列は領域の確保をRedimステートメントで上限値を指定する方法と、領域の拡張を行うRedim Preserveステートメントを指定する方法があります。

よく言われるのが、「領域の再確保(Redim Preserve)は遅いので、先に要素数を調べて領域の確保は最初に1回だけにしましょう」という話です。

これ自体はその通りで、Redim Preserveステートメントを行うと、拡張後の領域を探して元の領域から新しい領域にデータがコピーされて以降は新しい領域を利用する、といういくつもの段階があることから、時間が掛かる処理のため避けられるなら避けた方が処理速度の向上につながります。

では、Redimを事前にやっておくとどれぐらい速いのでしょうか? また、遅いと言われるRedim Preserveステートメントは、どれぐらい遅いのでしょうか?

Redimは常に高速

以下のコードは100万件のデータ領域を事前にRedimステートメントで確保します。

100万件の領域を確保したあとにループしていますが、処理時間は0.1秒前後です。

これぐらいであれば体感では全くわからず、高速です。

Redim Preserveは10万件を境に遅くなる?

PCの性能によって結果は異なると思いますが、指定回数ループしながらRedim Preserveを行う以下のコードで、ループ回数を変更しながらどれぐらい処理速度に変化があるのかを計測してみました。

結果は以下の通りになりました。

回数 秒数
10000 0.01464844 0
20000 0.0146484 0
30000 0.015625 0.0009766
40000 0.0307617 0.0151367
50000 0.0561523 0.0253906
60000 0.06591797 0.0097657
70000 0.078125 0.012207
80000 0.1191406 0.0410156
90000 0.1411133 0.0219727
100000 0.1870117 0.0458984
200000 0.717041 0.5300293
300000 1.64209 0.925049
400000 3.041016 1.398926
500000 4.679199 1.638183
600000 6.775879 2.09668
700000 9.109131 2.333252
800000 11.89917 2.790039
900000 14.97095 3.07178
1000000 18.43994 3.46899
1100000 22.47705 4.03711
1200000 26.90698 4.42993
1300000 31.37695 4.46997
1400000 36.33789 4.96094
1500000 41.87744 5.53955
1600000 47.65527 5.77783
1700000 53.69873 6.04346
1800000 60.47314 6.77441
1900000 67.13721 6.66407
2000000 74.38184 7.24463

このグラフの通り、10万件ぐらいまでは1秒未満程度ですが、そこを超えると処理秒数が上がっていきます。

100万件では20秒近くまで掛かっています。

件数が少ない場合はRedim Preserveを使っても影響は少ない

上の表やグラフの通り、配列の要素数が10万件未満の場合であれば、Redim Preserveを使っても処理速度にあまり影響がありません。

1万件程度のループであれば要素数を無理に取得して配列の要素数を事前決定するよりも、ループ内でRedim Preserveしてもほとんど問題がないでしょう。

私のPCでは10万件が境目になりましたが、環境によって異なると思います。