型によって速度に違いがある
プログラミング言語でたまに話題になるのが「数値型はこの型が一番速いのでこれを使いましょう」という話です。
VBAについても同じように型によって処理速度に違いが出ます。
そこで数値型のInteger型、Long型、Single型、Double型、Currency型の5つを比較してみます。
Byte型やBoolean型も数値型ではありますが、用途が違うので除外します。
先に答えを書いてしまうと、速かった順ではInteger、Long、Currency、Double、Singleでしたが、速度の違いは微々たるものなので、そんなことは気にせず品質の高いコードを書く方がよっぽど有益、です。
比較用コード
以下のコードで処理の開始と終了をマイクロ秒で取得して、開始と終了の差から処理時間を計測します。
処理自体は100000回×10000回、つまり10億回のループで足し算を行うプログラムです。
実行する際に2行目から6行目で計測対象の数値型のみコメントをはずして実行します。
比較には「VBAでミリ秒やマイクロ秒の計測を行う」で紹介しているマイクロ秒計測関数「GetMicroSecond」を利用しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Sub CompareDataType() Dim i As Integer ' Dim i As Long ' Dim i As Single ' Dim i As Double ' Dim i As Currency Dim id1 Dim id2 Dim microStart As Double Dim microEnd As Double Dim microDiff As Double microStart = GetMicroSecond For id1 = 1 To 100000 i = 0 For id2 = 1 To 10000 i = i + 1 Next Next microEnd = GetMicroSecond microDiff = microEnd - microStart Debug.Print microDiff End Sub |
比較結果
結果からいうと、以下の通り、Integer、Long、Currency、Double、Single、順に速かったです。
ただ、おおざっぱに言えば、Integer = Long > Currency > Double = Single といった感じになりました。
順位 | 数値型 | 平均速度 | 1位と速度差率 |
---|---|---|---|
1位 | Integer | 12.4480567194987 | 100.00% |
2位 | Long | 12.4500986955128 | 100.02% |
3位 | Currency | 15.1783854221925 | 121.93% |
4位 | Double | 18.5107456908387 | 148.70% |
5位 | Single | 18.7996578843275 | 151.02% |
IntegerとLongは0.02%しか違いがなく、ほとんど速度差はありませんでした。
意外だったのはCurrency型が結構速かったことです。
Currency型は15桁の整数と4桁の小数を保持できます。
扱う数値が整数15桁+小数4桁のCurrency型の範囲に入ることが分かっている場合は、Double型よりもCurrency型を利用した方が処理速度向上が見込めます。
SingleとDoubleでは、一般的には単精度(Single)と倍精度(Double)では単精度の方が速いと言われます。
VBAの実装は分からないのですが、言語によっては単精度は一度倍精度に変換して単精度に戻すようなものもあるため、そういう場合は倍精度(Double)の方が速かったりします。
なので、SingleとDoubleでDoubleが速かったのは私の環境だけかも、という点を補足しておきます。
ただ、10億回のループで12秒から19秒なので
テストコードは10億回ものループ処理を行っています。
10億回で12秒から19秒の範囲ですから、差なんて微々たるものでしかありませんし、テストコードに演算処理が増えれば一気に処理時間は増えることになります。
ここまでのループを行う処理は実際の処理ではなかなか無いと思います。
VBAにそこまでの高速性を求めるようなことはほとんどないでしょう。
その上での差ですので、PCの処理速度がどんどん向上している現在では、もはや型での速度の違いを言ってもほとんど意味を成さなくなっているのが現実です。
IntegerとLongの比較で、「Long型の方が速い。なのでLong型一択で大丈夫。」みたいなことを書いてあるサイトが結構あるのですが、VBAのバージョンによって実装が違いあったり、PC環境や演算の仕方によって、今回のようにInteger型が速いこともあります。
確かにオーバーフローの予防を考えるのであればIntegerと比べればLongを使った方がいいと思いますが、それはあくまでもInteger型と比較すればという話であってLong型でもオーバーフローは発生しますし、Integer型で回避できなかったものがLong型だからといって必ず回避できるというわけでもありません。
そのため、Integer型やLong型の用途を無視して無条件に「Long型でOK」、と言いきってしまうのはあまりにも速度偏重が強く、個人的には好みません。
むしろ、型の違いによる速度低下があったとしても、コーディングルールを適切に守りコードの品質を保つように努めた方がいいと思います。
比較結果詳細
細かいデータは特にいらないとは思いますが、上のコードを数値型ごとに5回ずつ実行した結果が以下になります。
そこまでばらつきも無い様子なので回数を増やしても変わらないと思い、5回ずつにしています。
数値型 | 回数 | 計測結果 | 平均 |
---|---|---|---|
Integer | 1回目 | 12.4729496697546 | 12.4480567194987 |
2回目 | 12.4415238746442 | ||
3回目 | 12.4542038372310 | ||
4回目 | 12.4340643484320 | ||
5回目 | 12.4375418674317 | ||
Long | 1回目 | 12.4478783314989 | 12.4500986955128 |
2回目 | 12.4387873804080 | ||
3回目 | 12.4419057826744 | ||
4回目 | 12.4624607504811 | ||
5回目 | 12.4594612325018 | ||
Single | 1回目 | 18.7943262018380 | 18.7996578843275 |
2回目 | 18.8006258363894 | ||
3回目 | 18.8132765399059 | ||
4回目 | 18.8008454335213 | ||
5回目 | 18.7892154099827 | ||
Double | 1回目 | 18.5085296386969 | 18.5107456908387 |
2回目 | 18.5132394270913 | ||
3回目 | 18.4997657733329 | ||
4回目 | 18.5088228454988 | ||
5回目 | 18.5233707695734 | ||
Currency | 1回目 | 15.1820697259391 | 15.1783854221925 |
2回目 | 15.1716516444285 | ||
3回目 | 15.1673936778679 | ||
4回目 | 15.1990255185228 | ||
5回目 | 15.1717865442042 |