一覧 検索 最終更新 改名 | ヘルプ | 最終更新のRSS |

memo/VB6 のバックアップソース(No.3)

*VB6 [#ic15ded2]
今更ながら Visual Basic 6.0 の、他ではあまり知られてない Tips をちょっと。


**コンパイル後に実行速度が遅くなる!? [#q4647ff0]

普段、書いたコードを EXE にコンパイルして実行すると、特にネイティブコンパイル時は IDE で実行する時よりも高速化して嬉しいのですが、実は反対に ''速度が極端に低下する状況'' というのが存在します。これに気が付くのにえらく時間が掛かってしまったのですが、原因を見付けたのでここにメモっておきます。

実は、よくある ''エラートラップ'' の処理がまさしくそれで、例えば次のようなコードを実行したとします:

 Dim i as Long, errCnt as Long, pObj(i) As Form
 
 On Local Error Resume Next
 
 For i = 0 To TESTCOUNT
     pObj(i).Caption = "a"       ' pObj(i) = Nothing なのでエラーとなる
     
     If Err.Number > 0 Then
         errCnt = errCnt + 1
         Err.Clear
     End If
 Next i

うちの Athlon XP 3200+ の環境で、この単純なループを 10 万回実行したとき、

-IDE環境内: 約 200 ms
-コンパイル後: 約 &color(red){800}; ms

と、かなりの速度差が発生します。 VB ではあまり無いとは思いますが、例えばフレームレート命!なゲームを制作してるときは、これは''かなり致命的な数字です''。

事前に防げるエラーはできる限り未然に防ぎましょう、ってことですね。


**空の動的配列に LBound() / UBound() を使ってもエラーを発生させない方法 [#b1c8975b]

上のエラートラップ関係で、個人的によくハマったものなのですが、解決策が見つかったので。

http://homepage1.nifty.com/MADIA/vb/vb_bbs/200312_03120035.html

>
 Private Declare Function SafeArrayAllocDescriptor Lib "oleaut32" _
   (ByVal cDims As Long, _
    ByRef ppsaOut() As Any) As Long
と宣言して、
 Dim X() As Test
 SafeArrayAllocDescriptor 1, X
を実行してみてください。UBound(X) が -1 になります。

//VB では Dim で配列を宣言するとき、要素数を指定しないと動的配列が生成できます。動的配列の要素数は、実行時に ReDim (Preserve) を実行することで変更することができます。これを利用して、「必要なときに要素を一つずつ増やす」といった使い方をよく行います。

//このとき、「配列内に存在している要素数」はどのようにカウントすればいいでしょうか。直接配列の要素をカウントする方法として、よく UBound() が利用されます。 UBound() は、''その配列の(指定された次元での)最後の添字'' を返す関数で、例えば ReDim hoge(10) と確保された配列に対して UBound(hoge()) は 10 を返します。これを利用すれば、その配列に存在する要素の数は ''UBound() + 1 個'' ということになります。

//しかし UBound() は、''初期化されていない配列に対してはエラーを発生します''。簡単に言えば、 ReDim されていない配列はエラーが発生

(HTML conversion costs 0.003 sec.)