StringBuilder for vb6

vb6にはJavaのStringBufferやVB.NETのStringBuilderが無いので自作してみた

ソース

Option Explicit

Private Const DEFAULT_BUFFER_SIZE As Long = 65536 'デフォルトバッファサイズ
Private Buffer As String 'バッファ
Private CurrentLength As Long '文字列長

'
' コンストラクタ
' あらかじめ設定されたバッファサイズで領域を確保する
'
Public Sub Class_Initialize()
  Call Clear(DEFAULT_BUFFER_SIZE)
End Sub

'
' 文字列を追加する
'
Public Sub Append(ByRef strAppendText As String)
  '追加する文字列がなかった場合何もしない
  If Len(strAppendText) = 0 Then
    Exit Sub
  End If
  
  '文字列長が足りなかった場合50%追加する
  Do While CurrentLength + Len(strAppendText) > Len(Buffer)
    Buffer = Buffer & String$(Len(Buffer) * 0.5 + 1, " ")
  Loop
  
  '末尾部分を置き換える
  Mid$(Buffer, CurrentLength + 1, Len(strAppendText)) = strAppendText
  
  '新しく文字列長を設定
  CurrentLength = CurrentLength + Len(strAppendText)
End Sub

'
' 文字列を返す
'
Public Function ToString() As String
  ToString = Left$(Buffer, CurrentLength)
End Function

'
' 文字列長を返す
'
Public Function Length() As Long
  Length = CurrentLength
End Function

'
' 指定されたサイズでバッファをクリアする
'
Public Sub Clear(ByRef Length As Long)
  Buffer = String$(Length, " ")
  CurrentLength = 0
End Sub

使い方

StringBuilder#Append(:String) 文字列を追加
StringBuilder#ToString():String 文字列を返す
StringBuilder#Length():Long 文字列長を返す
StringBuilder#Clear(:Long) バッファをクリアする

テスト

100,000回の文字列連結テストをしてみました。

ソース
Option Explicit

Private Const COUNT As Long = 100000
Private Declare Function timeGetTime Lib "winmm.dll" () As Long

Public Sub Main()
  Dim i As Long
  Dim startTime As Long

  'StringBuilderを使って文字列連結テスト
  startTime = timeGetTime
  Dim builder As New StringBuilder
  For i = 0 To COUNT - 1
    Call builder.Append("A")
  Next
  Debug.Print ("StringBulder : " & (timeGetTime - startTime) / 1000# & "[s]")
  
  'Stringを使って文字列連結テスト
  startTime = timeGetTime
  Dim s As String
  For i = 0 To COUNT - 1
    s = s & "A"
  Next
  Debug.Print ("String : " & (timeGetTime - startTime) / 1000# & "[s]")
End Sub
実行結果
StringBulder : 0.114[s]
String : 2.739[s]

けっこう違いますね!!