Concatenate strings using Mid$ Function - danielep71/VBA-PERFORMANCE GitHub Wiki
[Home]] ](/danielep71/VBA-PERFORMANCE/wiki/[[Tips-and-Tricks)
1. Statement
When it is necessary to repeatedly add sets of characters to the same variable, it is possible to speed up the code by resorting to a simple trick based on the Mid$ command.
2. Description
The basic string operator “&” performs a string concatenation.
Some programmers (maybe with roots in QuickBasic) still use the “+” operator for performing string concatenation. This could be a dangerous practice that might introduce unexpected behaviors when either operand is not a string.
As many know, the "&" operator or the “+” operators are quite slow, especially with long strings.
To speed up the concatenation on the same variable, it is possible to pre-allocate a buffer large enough to contain the result of the operation.
Example:
Suppose you want to create a string by adding the first 10,000 integers to it.
The simplest way is as follows:
sRes = ""
For i = 1 To 10000: sRes = sRes & Str(i): Next
The problem with this approach is that the sRes variable is reallocated 10,000 times. It is possible to obtain the same result with a more efficient technique:
- pre-allocate a buffer big enough to hold the final string using the Space Function;
 - use Mid$ function to build the final string.
 
3. Performance test
Sub Test_ConcatenateWithMid()
'Declare
    Dim i               As Long                     'Loop counter
    Dim MaxIter         As Long                     'Max # of iterations
    Dim iMethod         As Integer                  'Performance method
    Dim cPM             As cPerformanceMonitor      'Performance tracker
    Dim sRes            As String                   'Result string
    Dim lIndex          As Long                     'Counter
    Dim sSubStr         As String                   'Temp sub-string
    Dim lLength         As Long                     'Temp sub-string length
'------------------------------------------------------------------------------
'Initialize
    MaxIter = 100000
    iMethod = 2
    Set cPM = New cPerformanceMonitor
'------------------------------------------------------------------------------
'Test1
    sRes = vbNullString
    cPM.StartTimer (iMethod)
    For i = 1 To MaxIter
        sRes = sRes & str(i)
    Next i
    Debug.Print cPM.ElapsedTime(iMethod) & " - ""&"" concatenation"
'Test2
    sRes = vbNullString
    cPM.StartTimer (iMethod)
    For i = 1 To MaxIter
        sRes = sRes + str(i)
    Next i
    Debug.Print cPM.ElapsedTime(iMethod) & " - ""+"" concatenation"
'Test3
    sRes = vbNullString
    cPM.StartTimer (iMethod)
    sRes = Space(MaxIter * 10)
    lIndex = 1                          'Start from the first position
    For i = 1 To MaxIter
        sSubStr = Str(i)
        lLength = Len(sSubStr)
        Mid$(sRes, lIndex, lLength) = sSubStr
        lIndex = lIndex + lLength       'Index increment
    Next i
    sRes = Left$(sRes, lIndex - 1)      'Remove excess characters
    Debug.Print cPM.ElapsedTime(iMethod) & " - ""Mid$"" concatenation"
'------------------------------------------------------------------------------
'Exit
    Set cPM = Nothing
End Sub
4. Results
The results are the following:
Looping 100,000 times:
- 00:00:03 - 578 ms - 000 µs - 000 ns - "&" concatenation
 - 00:00:03 - 438 ms - 000 µs - 000 ns - "+" concatenation
 - 00:00:00 - 015 ms - 000 µs - 000 ns - "Mid$" concatenation
 
Using Mid$ with a pre-allocated buffer is more than 200 times faster!
5. Conclusions
Improvement: more than 200 times faster.
Impact: more than 3 seconds.
The test shows a very significant performance increase
[Home]] ](/danielep71/VBA-PERFORMANCE/wiki/[[Tips-and-Tricks)