McMillan's Visual Basic Code - Fast String concatenation with the String Class
Fast String concatenation with the String Class
Home

Comments

Every time you concatenate a String in Visual Basic, the String is redimensioned to the length of the new String. If you are doing multiple concatenations in a loop then this becomes very inefficient.

The String Class dimensions a buffer and only redimensions the buffer when it becomes full. So if you choose the buffer length wisely (the best size would be the final length of the string) then you can gain enormous efficiency from using the String Class.

You may notice that the CopyMemory API is used to insert the string to be appended into the buffer and that the Prepend method calls CopyMemory twice. This means that the Prepend method is approximately half as fast as the Append method (still a lot quicker than using Strings though).

Reference

StringClass Properties

Length

Read-Only

Return Type is a Long

Value [= s]

Read-Write

Return Type is a String

NameTypeDescription

sString

BufferSize [= Value]

Read-Write

Return Type is a Long

NameTypeDescription

ValueLong

StringClass Methods

LowerCase

UpperCase

CharacterAt (Pos)

Return Type is a String Value

NameTypeDescription

PosLong

FromRight (Length)

Return Type is a String Value

NameTypeDescription

LengthLong

FromLeft (Length)

Return Type is a String Value

NameTypeDescription

LengthLong

Prepend s

NameTypeDescription

sString

AppendLine s

NameTypeDescription

sString

Append s

NameTypeDescription

sString

Usage

Add StringClass.cls to your project

   'In this example the buffer will be redimensioned 10 times.
   'If the same loop was done with a String then it would require
   '1000 redimensions (which is 50 times slower on my computer).

   Dim s As StringClass
   Dim MyString As String
   Dim l As Long

   MyString = space(1000)

   Set s = New StringClass
   s.BufferSize = 100000
   For l = 1 To 1000
      s.Append MyString
   Next
   Set s = Nothing

The Code

StringClass.cls

Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As _
Any, pSrc As Any, ByVal ByteLen As Long)

Private StrLen As Long
Private Buffer As String

Public BufferSize As Long

Public Property Get Value() As String

   Value = Left$(Buffer, StrLen)

End Property

Public Property Let Value(s As String)

   Buffer = ""
   StrLen = 0
   Append s

End Property

Public Property Get Length() As Long

   Length = StrLen

End Property

Public Sub Append(s As String)

   Dim l As Long

   l = StrLen + Len(s)

   While l > Len(Buffer)
      Buffer = Buffer & space$(BufferSize)
   Wend

   CopyMemory ByVal StrPtr(Buffer) + (StrLen * 2), ByVal StrPtr(s), LenB(s)
   StrLen = StrLen + Len(s)

End Sub

Public Sub AppendLine(s As String)

   Append s
   Append vbCrLf

End Sub

Public Sub Prepend(s As String)

   Dim v As String
   Dim l As Long

   l = StrLen + Len(s)

   While l > Len(Buffer)
      Buffer = Buffer & space$(BufferSize)
   Wend

   v = Value

   CopyMemory ByVal StrPtr(Buffer) + LenB(s), ByVal StrPtr(v), LenB(v)
   CopyMemory ByVal StrPtr(Buffer), ByVal StrPtr(s), LenB(s)
   StrLen = StrLen + Len(s)

End Sub

Public Function FromLeft(Length As Long) As String

   If StrLen > Length Then
      FromLeft = Left$(Buffer, Length)
   Else
      FromLeft = Left$(Buffer, StrLen)
   End If

End Function

Public Function FromRight(Length As Long) As String

   If Length > StrLen Then
      FromRight = Mid$(Buffer, 1, StrLen)
   Else
      FromRight = Mid$(Buffer, (StrLen - Length) + 1, Length)
   End If

End Function

Public Function CharacterAt(Pos As Long) As String

   If Pos < StrLen + 1 And Pos > 0 Then
      CharacterAt = Mid$(Buffer, Pos, 1)
   End If

End Function

Public Sub UpperCase()

   Buffer = StrConv(Buffer, vbUpperCase)

End Sub

Public Sub LowerCase()

   Buffer = StrConv(Buffer, vbLowerCase)

End Sub

Private Sub Class_Initialize()

   BufferSize = 10000
   StrLen = 0

End Sub

Downloads

  StringClass.zip - contains: StringClass.cls (1 kb)

© Copyright Notice

Unless otherwise stated, the code on this site is Copyright to Andrew McMillan. You may use this code in your projects (both commercial and non-commercial) but you are not permitted to republish this code in any form without the Author's prior consent.

The code on this site is supplied "as is" and no claims are made as to its soundness. The Author claims no responsibility for or liability from use of said source code.

Home