配列の都度拡張は時間が掛かるのか(実験)
先日から、配列やコレクションの作成に掛かる時間を色々と測定している。
infoment.hatenablog.com
これらを通じて、ふと思いついた。総数が分からないものを配列に格納する際、Redimによる都度拡張は、思ったより時間が掛かっているのではないか。そこで、簡易的な実験を行ってみた。
総数が分かっている場合
まず測定基準として、こちらを用意した。
Sub test_1() Dim i As Long Dim seq(1 To 1000000) As Variant For i = 1 To 1000000 seq(i) = i Next End Sub
1~100万の要素数を持つ配列を作成。最初から範囲が分かっているので、それに合わせて配列を準備している。商品が100万個あることがわかっているので、最初に箱を100万個準備して箱詰めするイメージ。
測定結果は↓こちら。
例え要素数が100万でも、実行時間は0.0秒。ほとんど体感できない短時間で、処理が完了する。
配列を都度拡張する場合
次いで、値を一つ入れるたびに、配列を拡張してみた。
Sub test_2() Dim i As Long Dim seq() As Variant ReDim seq(1 To 1) For i = 1 To 1000000 seq(i) = i ReDim Preserve seq(1 To i + 1) Next ReDim Preserve seq(1 To i - 1) End Sub
商品が1個出てくるたびに、まず最後の1箱に商品を箱詰めして、次の箱を1個準備する。これを100万回繰り返すイメージ。
測定結果は↓こちら。
実行時間は25.9秒。250倍以上の時間が掛かっている。100万回の拡張作業が、「塵も積もれば山となる」で効いている。
一旦コレクションに格納する場合
最後に、一旦全てコレクションに格納する方法を試してみた。
Sub test_3() Dim i As Long Dim col As Collection Set col = New Collection For i = 1 To 1000000 col.Add i Next Dim seq() As Variant ReDim seq(1 To col.Count) Dim c As Variant i = 1 For Each c In col seq(i) = c i = i + 1 Next End Sub
一旦商品を全て倉庫に入れ、倉庫の中の商品数を数える。そして、その数分だけ箱を準備して箱詰めするイメージ。
測定結果は↓こちら。
実行時間は0.2秒。実質「2周」しているが、都度拡張より遥かに早い。
100万ものデータを扱うのでなければ、どの方式も差はないかもしれない。だが、どうも処理時間が遅いなと感じたら、敢えてコレクションに格納するという方式を試してみるのもありかもしれない。
参考まで。