昔、本項で比較したかったのは、要するに「For Next と For Each って、どっちが速いの?」ってことです。1995年にMicrosoftから出版されたVBAに関する公式本に「For Each の方が速いよ~理由はね~」って書いてあったからです。その頃調べた結果では、確かに For Each の方が速かったです。でも、時代は変わりました。と同時に、パソコンの性能も飛躍的に向上しています。理論的に速くても、体感速度として、あるいは計測結果としては、どうなんでしょう。
まず、For Next と For Each で比較してみましょう。
Sub Test1() Dim i As Long For i = 1 To 10000 Cells(i, 1) = 100 Next i End Sub
Sub Test2() Dim c As Range For Each c In Range("A1:A10000") c = 100 Next c
回 | For Next | For Each | % |
---|---|---|---|
1 | 3.703 | 3.703 | 100.0% |
2 | 3.641 | 3.687 | 101.3% |
3 | 4.218 | 3.719 | 88.2% |
4 | 3.719 | 4.297 | 115.5% |
5 | 3.687 | 4.031 | 109.3% |
6 | 3.688 | 3.625 | 98.3% |
7 | 3.656 | 4.422 | 121.0% |
8 | 4.219 | 3.953 | 93.7% |
9 | 3.891 | 3.688 | 94.8% |
10 | 4.000 | 4.250 | 106.3% |
平均 | 3.842 | 3.938 | 102.5% |
でもまぁ考えてみれば、For Next と For Each って、考え方や使い方がそもそもまるで違うのですから、単純に"どっちが速い"って話じゃないように思います。だって、For Next のカウンタ変数は一般的にLong型ですし、対して For Each の制御変数は、オブジェクト型またはバリアント型ですから。すでに、そこが違っているわけですから、単純な比較はできないな~と。今になってそう思います。
でも、せっかくですから、もう少し検証してみましょう。上記のマクロは、1つのセルしか使っていません。でも、もし同じ行の複数セルを扱う場合。For Next なら次のように書けます。
Sub Test3() Dim i As Long For i = 1 To 10000 Cells(i, 1) = Cells(i, 2) + Cells(i, 3) Next i End Sub
対して For Each で同じことをやるなら、次のようになりますね。
Sub Test4() Dim c As Range For Each c In Range("A1:A10000") c = c.Offset(0, 1) + c.Offset(0, 2) Next c
Offsetが出てきました。さて、速度はどうでしょう。
回 | For Next | For Each | % |
---|---|---|---|
1 | 4.125 | 3.859 | 93.6% |
2 | 4.563 | 3.875 | 84.9% |
3 | 3.766 | 3.828 | 101.6% |
4 | 3.843 | 3.797 | 98.8% |
5 | 3.797 | 3.765 | 99.2% |
6 | 3.766 | 3.781 | 100.4% |
7 | 3.750 | 3.781 | 100.8% |
8 | 3.781 | 4.532 | 119.9% |
9 | 3.766 | 4.485 | 119.1% |
10 | 4.547 | 3.750 | 82.5% |
平均 | 3.970 | 3.945 | 99.4% |
それほど変わりませんね。ちなみにVBAにはもうひとつ、Do Loopという繰り返しステートメントがあります。まぁ、ワークシート上のセルなどを操作するのでしたら、ほとんど使う機会もないのですけど。ああ、参考までに、本当を言うとVBAにはもうひとつ、While Wend という繰り返しもありますが、知ってる人はほとんどいないだろうし、使う必要性もないのでここでは触れません。
Sub Test5() Dim i As Long Do While i <= 10000 i = i + 1 Cells(i, 1) = Cells(i, 2) + Cells(i, 3) Loop End Sub
回 | For Next | Do Loop | % |
---|---|---|---|
1 | 4.125 | 3.891 | 94.3% |
2 | 4.563 | 3.844 | 84.2% |
3 | 3.766 | 4.422 | 117.4% |
4 | 3.843 | 3.875 | 100.8% |
5 | 3.797 | 3.796 | 100.0% |
6 | 3.766 | 3.813 | 101.2% |
7 | 3.750 | 3.781 | 100.8% |
8 | 3.781 | 3.781 | 100.0% |
9 | 3.766 | 3.782 | 100.4% |
10 | 4.547 | 4.593 | 101.0% |
平均 | 3.970 | 3.958 | 99.7% |
昔の古いPCではともかく、現在のPCだったら、For Next だろうが For Each だろうが、ましてや Do Loop であっても、それほど速度差はないってことですかね。