C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

VBAのリスト問題2

こちらの続きです。
VBAのリスト問題1 - C#ATIA

続いては固定長配列です。もう、やらなくてもこれが一番速いのが
分かっているのですが、指標的な意味合いです。

Private Sub test3( _
    ByVal Count As Long)

    Dim ary(50000) As Long
    
    Dim i As Long
    For i = 0 To Count - 1
        ary(i) = i
    Next
    
    sw_.split "Long 代入:"
    
    Dim x As Long
    For i = 0 To UBound(ary)
        x = ary(i)
    Next

    sw_.split "呼出:"

    
    sw_.split "--:"
    Dim objAry(50000) As myObj
    Dim obj As myObj
    Set obj = New myObj
    
    For i = 0 To Count
        Set objAry(i) = obj
    Next
    
    sw_.split "Object 代入:"
    
    For i = 0 To UBound(ary)
        Set obj = objAry(i)
    Next
    
    sw_.split "呼出:"

End Sub

結果はこちら。

**固定長配列**
Long 代入:0.0078125s
呼出:0s
--:0s
Object 代入:0.0078125s
呼出:0.0078125s
**終了** :0.046875s

2倍とか3倍とかでは無く、2桁ぐらい違いますね。
但し、コードを書く時点で必要最大サイズが分かる場面はほぼ無く、
不必要なサイズの配列用意するのも、ちょっと違うような
気もしてます。正直な所、使い道としては無いですよね。


続いては動的配列です。使用する場面の多さから、これを”配列”と
呼びたいところです。

Private Sub test4( _
    ByVal Count As Long)

    Dim ary() As Long
    ReDim ary(Count)
    
    Dim i As Long
    For i = 0 To Count - 1
        ary(i) = i
    Next
    
    sw_.split "Long 代入:"
    
    Dim x As Long
    For i = 0 To UBound(ary)
        x = ary(i)
    Next

    sw_.split "呼出:"

    
    sw_.split "--:"
    Dim objAry() As myObj
    ReDim objAry(Count)
    
    Dim obj As myObj
    Set obj = New myObj
    
    For i = 0 To Count
        Set objAry(i) = obj
    Next
    
    sw_.split "Object 代入:"
    
    For i = 0 To UBound(ary)
        Set obj = objAry(i)
    Next
    
    sw_.split "呼出:"

End Sub

結果の一例です。

**可変長配列**
Long 代入:0.015625s
呼出:0.0078125s
--:0s
Object 代入:0s
呼出:0.015625s
**終了** :0.0390625s

ちょっと驚いたのは、オブジェクトの代入が固定長配列より
速かった事です。何でだろう?


次は同じ動的配列なのですが、最初にサイズが決められない
ような状態の場合、単なるReDimでは無く、ReDim Preserveで
サイズを大きくする方法があります。
このPreserveを使った極端な例として、代入を行う直前に
1個づつサイズを広げ代入するようにしたものです。

Private Sub test5( _
    ByVal Count As Long)

    Dim ary() As Long
    
    Dim i As Long
    For i = 0 To Count - 1
        ReDim Preserve ary(i)
        ary(i) = i
    Next
    
    sw_.split "Long 代入:"
    
    Dim x As Long
    For i = 0 To UBound(ary)
        x = ary(i)
    Next

    sw_.split "呼出:"

    
    sw_.split "--:"
    Dim objAry() As myObj
    
    Dim obj As myObj
    Set obj = New myObj
    
    For i = 0 To Count
        ReDim Preserve objAry(i)
        Set objAry(i) = obj
    Next
    
    sw_.split "Object 代入:"
    
    For i = 0 To UBound(objAry)
        Set obj = objAry(i)
    Next
    
    sw_.split "呼出:"

End Sub

結果の一例です。

**可変長配列 Preserve**
Long 代入:0.03125s
呼出:0s
--:0s
Object 代入:0.0390625s
呼出:0.015625s
**終了** :0.109375s

思ったより、差が出なかった・・・。
ループさせる回数が少ないからだろうと思います。

と言う事で、動的配列の2種類を50000->500000に
増やした結果の一例がこちら。

**可変長配列**
Long 代入:0.0234375s
呼出:0.0234375s
--:0s
Object 代入:0.046875s
呼出:0.0546875s
**終了** :0.1640625s

**可変長配列 Preserve**
Long 代入:0.9375s
呼出:0.0234375s
--:0s
Object 代入:0.890625s
呼出:0.046875s
**終了** :1.9296875s

呼び出しについては、まぁ同じ処理なので誤差です。
代入については結構な差が付きました。
理由が分かっているのですが、他を試した際に書こうかな?と
思ってます。