VBAの整数計算はLongだけでいい (Variant, Integerとの実行時間の違い)

MSの公式ドキュメントにこんな記載があることを教えていただいた。

[For... の高速化次のループ (VBA) | Microsoft Learn](https://learn.microsoft.com/ja-jp/office/vba/language/concepts/getting-started/making-faster-fornext-loops)


> 整数が使用するメモリ量は バリアント型 (Variant) よりも少なくて済み、更新速度が少しだけ速くなります。
> ただし、実行する操作の数が膨大になると、この少しの違いが目立ちます。 

どのぐらい違うんだろう？？
御託は抜きで確かめるのが一番早い

# 実際に計ってみる

Integer, Long, Variantでランダムな数値を1億回引き算してみる

賢い言語だと、計算した値を使わないようなコード書くと最適化されてそもそも計算しなかったりするので、一応戻り値を使うようなものにしてみる
(まぁVBAではされないんですけど)

```vb
Const MAX_REP As Long = 100000000

Function rand_int() As Integer
    rand_int = Rnd * 32767
End Function

Function rand_long() As Long
    rand_long = Rnd * 2147483647
End Function

Function rand_variant() As Variant
    rand_variant = rand_int
End Function

Function loop_int() As Integer
    Dim i As Long
    For i = 0 To MAX_REP
        loop_int = rand_int - rand_int
    Next
End Function

Function loop_long() As Long
    Dim i As Long
    For i = 0 To MAX_REP
        loop_long = rand_long - rand_long
    Next
End Function

Function loop_variant() As Long
    Dim i As Long
    For i = 0 To MAX_REP
        loop_variant = rand_variant - rand_variant
    Next
End Function

Sub main()
    Range("A:C") = ""
    Range("A:C").NumberFormat = "0.000000 秒"
    Range("A1:C1").NumberFormat = 0
    
    Dim i As Long, start As Single
    For i = 2 To 4
        start = Timer
        Cells(1, 1) = loop_int
        Cells(i, 1) = Timer - start
        
        start = Timer
        Cells(1, 2) = loop_long
        Cells(i, 2) = Timer - start
        
        start = Timer
        Cells(1, 3) = loop_variant
        Cells(i, 3) = Timer - start
        
        DoEvents
    Next
    
    Range("A1:C1") = Array("Integer", "Long", "Variant")
End Sub
```

# 結果

合計9億回の無駄な引き算をさせた結果:

| Integer | Long | Variant |
| --- | --- | --- |
| 29.941406 秒 | 29.369141 秒 | 41.693359 秒 |
| 29.863281 秒 | 30.160156 秒 | 41.636719 秒 |
| 29.910156 秒 | 29.427734 秒 | 40.843750 秒 |

- Integer: 約30秒
- Long: 約30秒
- Variant: 約40秒

という結果になりました。Variant型と比較すると1.3倍速くなるようです！
他にも型チェックしてくれるなどメリットはあるのでVariant型はなるべく避けようの会に入会しよう

一方、IntegerとLongは変わらないですね

# なんで？

(当たり前すぎてめんどいのでChatGPT先生に書いてもらいました: [ChatGPT](https://chatgpt.com/share/ec5605e3-52ee-4a59-ad78-ad25efc62118))

まず、メモリ空間が違います。

| 型 | メモリサイズ | 最大値 |
| --- | --- | --- |
| Integer | 2バイト | 32,767 |
| Long | 4バイト | 2,147,483,647 |
| Variant | 可変 (16バイト) | 可変 |

### メモリ使用の違いによる影響

Variant型は、他の単純なデータ型よりも多くのメモリを使用します。
これは、Variant型がデータ型情報を保持し、メタデータを管理するためです。
この追加のメタデータの管理とアクセスにはオーバーヘッドが伴い、そのためメモリ使用量が多くなり、計算速度が遅くなる原因となります。

### 計算方法の違い

Variant型は、データ型の確認と適切な型への変換を行うため、計算が単純な整数型よりも遅くなります。
具体的には、Variant型はその中に格納されたデータ型を動的に決定し、計算を実行する際にその型に基づいた処理を行います。
この過程には追加の処理時間がかかります。

### IntegerとLongの計算時間が同じ理由

現代の64ビットCPUでは、レジスタのサイズが64ビットであり、一度に64ビットまでのデータを処理できます。
したがって、16ビットのInteger型も32ビットのLong型も、計算サイクルに大きな違いがありません。
どちらも1回のCPUサイクルで処理できるため、実行時間にほとんど差が生じないのです。

また、VBAのLongは他の多くのプログラミング言語におけるintと同じ32ビットの整数型です。
つまり、他の言語で標準的に使用される整数型と同じ仕様なので、特に考えずにLongを使用するのが便利で安心です。

これらの理由から、整数計算においてはLong型を使用することが最適であり、Variant型の使用は避けるべきであることがわかります。

# Integer使う意味ってあるの？

ありません。

メモリ容量は違いますがそもそも他の言語の整数型では32bit(4byte)がデフォなわけです。
VBAが古いまま進化してないだけです。

整数計算の途中でたかが3万超えたあたりでいちいちエラー出ることに精神を削られる必要はありません。
LongをIntegerにして何とかなるような場面は存在しません。逆は無限にあります。