今回は「VB6.0やVBAだとこういう書き方もアリなんだー」という、個人的には目から鱗ネタです。下記のソース、(1)と(2)、どちらが速いか?というわけですね。
(1)For i = 0 To lngMax strText1 = strText1 & "あいうえおかきくけこさしすせそ" Next(2)
For i = 0 To lngMax strText2 = strText2 & "あいうえおかきくけこさしすせそ" If Len(strText2) > 3000 Then strText1 = strText1 & strText2: strText2 = vbNullString Next If Len(strText2) Then strText1 = strText1 & strText2
(1)の方が一般的な書き方だと思いますが、この場合、(2)の方が圧倒的に速いのです。
結果
(1):343 ミリ秒
(2):16 ミリ秒
※Acceess2003で実験
VB6.0のString型は値型なので文字列を追加する度に、データの文字列をコピーしているわけですね。コピーするものが、長ければ長いほど、コピーの作業にコストがかかる。
ひるがえって(2)ではstrText2にちまちま文字列を追加して、
If Len(strText2) > 3000
のタイミングでstrText1に突っ込んで、strText2をカラッポにしてまた文字列をためていく。その方が、長い文字列をコピーする回数が激減して、処理が速くなるというわけなんですね(ちなみに.Netだとstring型は一応参照型なので、文字列をセットする度にコンストラクタが発生している様子でVB6.0/VBAどころではない負荷を、もはや「体感」として感じます。なのでStringBuilderのインデクサで対応)。
サンプルソース
フォームにtxtDATAという名前のテキストボックスを作って、そこにタイムを表示する。clsTimerMMクラスは「時間経過計測クラス‐VBA編」参照。
Dim clsTimerMM As clsTimerMM Dim strTextMsg As String '************************ Dim strMsg As String Dim strText1 As String Dim strText2 As String Dim lngMax As Long Dim i As Long '************************ Set clsTimerMM = New clsTimerMM strMsg = "あいうえおかきくけこさしすせそ" lngMax = 10000 '************************ clsTimerMM.SetStartDate For i = 0 To lngMax strText1 = strText1 & strMsg Next strTextMsg = "(1):" & clsTimerMM.ElapsedTime & vbCrLf Me.txtText1.Value = strText1 & vbCrLf strText1 = vbNullString '************************ clsTimerMM.SetStartDate For i = 0 To lngMax strText2 = strText2 & strMsg If Len(strText2) > 3000 Then strText1 = strText1 & strText2: strText2 = vbNullString Next If Len(strText2) Then strText1 = strText1 & strText2 strTextMsg = strTextMsg & "(2):" & clsTimerMM.ElapsedTime & vbCrLf Me.txtText2.Value = strText1 & vbCrLf Me.txtDATA.Value = strTextMsg Set clsTimerMM = Nothing
0 件のコメント:
コメントを投稿