【问题标题】:Creating a string from an array of strings. Fastest method?从字符串数组创建一个字符串。最快的方法?
【发布时间】:2015-09-06 04:18:09
【问题描述】:

我有一个字符串数组(A 到 E),我想加入一个字符串(“A B C D E”)。我应该循环遍历数组还是使用 Join 函数?

Dim MyArray(5) as String
Dim MyString as String

MyArray(1) = "A"
MyArray(2) = "B" 
MyArray(3) = "C" 
MyArray(4) = "D" 
MyArray(5) = "E" 

哪个更快更明智?

这个?

MyString = MyArray(1)
For i = 2 To 5
    MyString = MyString & " " & MyArray(i)
Next

还是这个?

MyString = Join(MyArray, " ")

【问题讨论】:

  • 我假设 join 会更快,因为它是在本机代码中实现的,而您在每次迭代中使用 for 循环增长字符串并调用两次连接运算符。可能会在前后获取系统时间(使用更大的数组)可以提供一些线索,说明哪个更好。
  • 我建议您使用对您个人来说更具可读性的解决方案。对我来说,这就是 Join,因为它在概念上更简单,并且避免了一个错误和其他可能的细微错误。为什么您认为与您的应用程序所做的其他事情相比,这段特定代码的性能对您的应用程序更重要?
  • 在构建字符串时,切勿将长字符串与两个短字符串连接(强制将长字符串复制两次)。所以而不是MyString = MyString & " " & MyArray(i) 使用MyString = MyString & (" " & MyArray(i))

标签: vba


【解决方案1】:

对于 100k 数组

Sub test()

    Dim aArr(1 To 100000) As String
    Dim i As Long
    Dim sString As String
    Dim snTimer As Single

    FillArray aArr

    snTimer = Timer

    For i = 1 To 100000
        sString = sString & Space(1) & aArr(i)
    Next i

    Debug.Print Timer - snTimer
    snTimer = Timer

    sString = Join(aArr, Space(1))

    Debug.Print Timer - snTimer

End Sub

加入是明显的赢家

 2.050781 
 0 

原因是每次与& 连接时,都必须重新分配内存以容纳新数组(无论如何,所有字符串都是如此)。使用 Join,您只需将一个数组(源数组)复制到另一个数组(字符串)并且 VBA 已经知道大小。

【讨论】:

  • 我发现这非常有用,但我只是注意到它取决于元素的数量/长度。例如,将长文本拆分为一组单词,然后在每个单词后面添加一个空格。我刚刚在字符串数组或变量数组中预先设置的相同两个元素上测试了 "dog" & " "join() 的 1000 万次迭代。在那种情况下,简单的连接显然更快(在我的测试中,Variant/Variant(0 到 1)大约 1.7 秒到 3.5 秒,字符串(0 到 1)大约 2.2 秒)。
【解决方案2】:

如果您想有效地组合多个字符串,您可以定义一个stringbuilder 类。

运行下面的代码来构建一个多达一百万的数字字符串只需要几分之一秒 (0.3 秒)。构建一个数组并使用Join 花费的时间不远(0.25 秒),而调用Join 函数只需要大约10% 的时间。

如果字符串已经在一个数组中,那么使用Join 是有意义的,但如果字符串数量较少,则无论如何都不太可能注意到差异。

Sub JoinStringTest()

Dim i As Long, t As Double
Dim sb As New StringBuilder
Dim sbRet As String
Dim joinRet As String

t = Timer
For i = 1 To 1000000
  sb.Append CStr(i)
Next
sbRet = sb.Text
Debug.Print "SB", Timer - t

t = Timer
Dim a(1000000) As String
For i = 1 To 1000000
  a(i) = CStr(i)
Next i
joinRet = Join(a, "")
Debug.Print "Join", Timer - t

Debug.Print sbRet = joinRet

End Sub

【讨论】:

    猜你喜欢
    • 2019-02-16
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 2021-10-29
    • 2013-09-21
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多