トップページ >
Excel >
VBA >
高速化テクニック >
タイプを指定しろ!
タイプを指定しろ!
昔から「こんなとき変数の型は…」という話題はプログラマたちにとって永遠のテーマでした。なぜなら、使用する変数の型によってプログラムのサイズや、実行速度が大きく変わると言われていたからです。では、VBAではどうなのか。さっそく検証してみましょう。
| | Test1 | Test2 | % |
| 1回目 | 00:47 | 00:29 | 61.7% |
| 2回目 | 00:47 | 00:30 | 63.8% |
| 3回目 | 00:47 | 00:29 | 61.7% |
| 4回目 | 00:48 | 00:29 | 60.4% |
| 5回目 | 00:47 | 00:29 | 61.7% |
| 6回目 | 00:47 | 00:31 | 66.0% |
| 7回目 | 00:46 | 00:30 | 65.2% |
| 8回目 | 00:47 | 00:31 | 66.0% |
| 9回目 | 00:45 | 00:30 | 66.7% |
| 10回目 | 00:46 | 00:31 | 67.4% |
| 平均 | 00:47 | 00:30 | 64.0% |
Sub Test1()
Dim i As Variant, j As Variant
For i = 1 To 30000
For j = 1 To 30000
Next j
Next i
End Sub
Sub Test2()
Dim i As Integer, j As Integer
For i = 1 To 30000
For j = 1 To 30000
Next j
Next i
End Sub
変数を使うとき、メモリの内部ではその変数分の領域を確保します。大きいデータを入れる変数は大きな領域を必要とし、小さい変数は小さい領域で済みます。そこで当然予想できるのは、大きい領域の変数は小さい変数に比べて使用に時間がかかるということです。
上記の検証は、For Nextステートメントを繰り返すだけの何もしないマクロです。ここで問題になるのは、
カウンタ変数の型です。Test1ではバリアント型(
Variant)、Test2では整数型(
Integer)を使ってみました。結果は明かです。
バリアント型は何でも格納できる万能の変数型です。数値なら膨大な桁数を格納できます。一方の整数型は32,767から-32,767の数値だけを格納できるコンパクトな変数型です。For Nextステートメントのように何度も変数を操作するケースでは、この差が大きく影響してきます。
それなら、カウンタ変数は整数型で宣言すればいい…と理解できたものの、変数の
宣言方法を誤ってはいけません。次のコードは3つの変数を宣言していますが、整数型で宣言されているのは最後の「k」だけです。最初の2つ「i」と「j」は整数型ではなくバリアント型変数になります。
Sub Sample()
Dim i, j, k As Integer
End Sub
「iとjとkを整数型で」と宣言したつもりでも、VBAでは「
iとjは型を省略、kは整数型で」という宣言になるのです。そしてこれもVBAのルールですが、変数の型を省略して宣言したとき、その変数はバリアント型になってしまいます。3つの変数全てを整数型で宣言するには、次のように書かなければなりません。
Sub Sample()
Dim i As Integer, j As Integer, k As Integer
End Sub
さて、変数には他にも多くの型があります。他の型では速度がどう違うのでしょう。Test1と同じコードで、変数の型だけを変えて検証してみましょう。
| | Test3 | Test4 | % |
| 1回目 | 00:32 | 00:42 | 131.3% |
| 2回目 | 00:30 | 00:42 | 140.0% |
| 3回目 | 00:31 | 00:42 | 135.5% |
| 4回目 | 00:30 | 00:41 | 136.7% |
| 5回目 | 00:31 | 00:42 | 135.5% |
| 6回目 | 00:30 | 00:41 | 136.7% |
| 7回目 | 00:31 | 00:41 | 132.3% |
| 8回目 | 00:30 | 00:43 | 143.3% |
| 9回目 | 00:30 | 00:41 | 136.7% |
| 10回目 | 00:30 | 00:42 | 140.0% |
| 平均 | 00:31 | 00:42 | 136.7% |
Sub Test3()
Dim i As Long, j As Long
For i = 1 To 30000
For j = 1 To 30000
Next j
Next i
End Sub
Sub Test4()
Dim i As Double, j As Double
For i = 1 To 30000
For j = 1 To 30000
Next j
Next i
End Sub
Longは長整数型といって2,147,486,647までの整数を格納できます。なんと整数型(
Integer)の約65、000倍。ところが実際は整数型(
Integer)と比べてあまり差はありません。Test4で宣言した
Doubleは倍精度浮動小数点型と呼ばれる型で、正の数は約4.9×10の-324乗〜1.8×10の308乗という…まぁ、要するに一般的なユーザーが使うのなら何も問題ない桁数を格納できるわけです。もちろん高速性は期待できません。
次は文字列型(
String)とバリアント型(
Variant)を比較してみましょう。
| | Test5 | Test6 | % |
| 1回目 | 00:30 | 00:37 | 123.3% |
| 2回目 | 00:30 | 00:36 | 120.0% |
| 3回目 | 00:31 | 00:37 | 119.4% |
| 4回目 | 00:30 | 00:37 | 123.3% |
| 5回目 | 00:30 | 00:37 | 123.3% |
| 6回目 | 00:30 | 00:37 | 123.3% |
| 7回目 | 00:29 | 00:37 | 127.6% |
| 8回目 | 00:30 | 00:37 | 123.3% |
| 9回目 | 00:29 | 00:36 | 124.1% |
| 10回目 | 00:29 | 00:36 | 124.1% |
| 平均 | 00:30 | 00:37 | 123.2% |
Sub Test5()
Dim i As Integer, j As Integer, tmp As String
For i = 1 To 10000
For j = 1 To 10000
tmp = "tanaka"
Next j
Next i
End Sub
Sub Test6()
Dim i As Integer, j As Integer, tmp As Variant
For i = 1 To 10000
For j = 1 To 10000
tmp = "tanaka"
Next j
Next i
End Sub
とまあ、変数の型によってマクロの実行速度が変わるわけです。私も拙著の中で「適切な型を宣言しましょう」と何度か書いています。しかし、最近になって考え方が変わりました。
最近のパソコンは非常に高速です。また、1秒が問題になるような速度重視のマクロを作る機会も、それほど多くはありません。それなら、Selectしないなど一般的な高速化に気を付けていれば、変数はバリアント型を多用してもいいんじゃないかな?って。
いくら速度的に不利だからといっても、やはり「Dim i As Integer, j As Integer, k As Integer」と書くよりも「Dim i, j, k」の方が簡単ですからね。速度的には不利だが記述の簡便さを重視して、あえて省略している…という認識を持てば、バリアント型の多用も悪くないと思います。まぁ、For Nextステートメントのカウンタ変数にバリアント型を使うのは、いささか抵抗もありますけど(^^;
[個別に呼ぶな!]戻る← | →進む[名前で呼ぶな!]