The Join Function

The Join function concatenates a bunch of strings in an array into one long string. I rarely use this function, but maybe I should start, as JP suggests. I wondered if it was really that much faster.

Declare Function timeGetTime Lib “winmm.dll” () As Long

Sub TestJoin()
   
    Dim i As Long
    Dim aInput() As String
    Dim lStart As Long
    Dim sOutput As String
   
    Const lLOOP As Long = 100000
    Const lBLOCK As Long = 100
   
    lStart = timeGetTime
   
    For i = 1 To lLOOP
        sOutput = sOutput & “a”
    Next i
   
    Debug.Print “Concetante: “ & timeGetTime – lStart
    lStart = timeGetTime
   
    ReDim aInput(1 To lLOOP)
    For i = 1 To lLOOP
        aInput(i) = “a”
    Next i
    sOutput = Join(aInput)
   
    Debug.Print “Join: “ & timeGetTime – lStart
    lStart = timeGetTime
   
    For i = 1 To lLOOP
        ReDim Preserve aInput(1 To i)
        aInput(i) = “a”
    Next i
    sOutput = Join(aInput)
   
    Debug.Print “Preserve: “ & timeGetTime – lStart
    lStart = timeGetTime
   
    ReDim aInput(1 To lBLOCK – 1)
    For i = 1 To lLOOP
        If i Mod lBLOCK = 0 Then ReDim Preserve aInput(1 To i + lBLOCK – 1)
        aInput(i) = “a”
    Next i
    sOutput = Join(aInput)
   
    Debug.Print “Block: “ & timeGetTime – lStart
   
End Sub

The next time I need to concatenate 100,000 characters will be the first time, but I’ll be sure to use Join. When I changes lBLOCK to 1,000, I get this.

Posted in Uncategorized

10 thoughts on “The Join Function

  1. this seems to be just as fast as Join (I’m not saying it’s better, just different)

    s = String(lLOOP, “|”)
    For i = 1 To lLOOP
    Mid$(s, i, 1) = “a”
    Next i

  2. I noticed that the outputs are not the same. Concetante does not have a space in the output. Example strings are shown below.

    Concetante: 1831
    aaaaaaaaaaaaaaaaa

    Join: 62
    a a a a a

    Preserve: 118
    a a a a a a a a

    Block: 71
    a a a a a a

  3. @dermotb,

    You posted this…

    s = String(lLOOP, “|”)
    For i = 1 To lLOOP
    Mid$(s, i, 1) = “a”
    Next i

    If all you are doing is creating multiple copies of the letter “a”, why create multiple copies of the vertical bar first only to replace them later on, just create multiple copies of the letter “a” directly…

    s = String(lLoop, “a”)

    I would also note that if you wanted to do your replacement later on, why use a loop when you can do this instead…

    s = String(lLoop, “|”)
    …..
    …..
    s = Replace(s, “|”, “a”)

    and avoid the loop altogether. Building on this idea, you can use the Space function (you could also use the String function if you wanted to type more characters for some reason) and the Replace function, in combination, in order to produce multiple copies of text strings containing more than one character (the String function is limited to repeating single characters, so it has no advantage over using the Space function). For example, let’s say you wanted to produce the text string “ABCABCABC…ABC” where the ABC is repeated, say, 20 times; you can do it this way…

    s = Replace(Space(20), ” “, “ABC”)

  4. Concatenation stinks when everything to be concatenated is already in one 1-D array, but mashing many separate strings in different variables into a single array just so one may use Join could be just as inefficient.

    If it’s the string allocations rather than the string copying that’s the performance drag, it’s best to allocate one huge string buffer and fill it using Mid$(..) = .., as dermotb suggests. That’s the classic approach, and probably close to how Join works. The problem with Join is its single data argument syntax.

  5. Rick, naturally if all the characters were the same you’d use STRING. However, I assumed that Dick knew this too, and that he only used the same character for testing purposes, and that in practice they would be different.

  6. I do agree with Dermotb that if all the characters are the same, we should use STRING. I think whether to use concatenation or join is also depends on the situation. If you have an array of string, especially the strings are long, I think join could be faster. It also depends on how many element you have, i guess :)

  7. If you want to populate an array with the same multi-character string, an alternative can be:

    sq = ([transpose(left(“ABCDEFG”&row(1:400),7))]

    if you want to join the array to 1 string without separating spaces:

    c01=Join([transpose(left(“ABCDEFG”&row(1:400),7))],“”)

Leave a Reply

Your email address will not be published. Required fields are marked *