Excel VBA 数组的工作表函数与代码的性能

Excel VBA performance of worksheetfunction vs code, for arrays

为了加快我的 VBA 代码速度,我在网上搜索了一些方法。很多方法都经过了,其中一个不断返回的方法似乎是在可能的情况下使用工作表函数代替代码

然而,我的经验与该提示相反。我发现 worksheetfunctions 往往比我的代码 慢。我下面的简单测试表明代码比工作表函数快两倍。我发现其他函数的结果相同,例如 MATCH。

那么我的问题是,你们 VBA 的人倾向于使用代码还是工作表函数?是否有理由在代码上使用函数(除了几行额外代码)?

Sub testSum()

    Dim testarray(0 To 10000) As Variant
    Dim val As Variant
    Dim valSum As Variant
    Dim i As Long, j As Long
    Dim t As Single

    ' create testarray
    For i = 0 To 10000
        testarray(i) = Rnd
    Next
    For i = 0 To 10000 Step 100
        testarray(i) = "text"
    Next

    ' measure code
    t = Timer
    For j = 1 To 10000
        valSum = 0
        For Each val In testarray
            If IsNumeric(val) Then valSum = valSum + val
        Next
    Next
    Debug.Print "Array: ", Int(valSum), Timer - t

    ' measure function
    t = Timer
    For j = 1 To 10000
        valSum = 0
        valSum = Application.WorksheetFunction.Sum(testarray)
    Next
    Debug.Print "Sum: ", Int(valSum), Timer - t

End Sub

我几乎只使用代码。

这可能是个问题,但我讨厌使用函数,因为我发现我总是必须返回并编辑位,这只会让我感到困惑,如果我可以只用一个 Sub m 使用代码。

为了回答您的代码,我可能会说只使用数组求和 - 这会减少几皮秒

尝试并使用 Code Review 来让那些聪明人提高你的速度

我更喜欢使用工作表中的工作表功能。在宏中测量函数是一种不公平的测试,因为 VBA 环境必须切换到 Excel 环境才能获得结果,这会增加否则不存在的开销。

作为一般编码规则,我的优先事项是:

  • 使用原生 Excel 公式,包括设置辅助单元格或 列。
  • 对数组使用 VBA
  • 使用 VBA 和 运行ges

作为测试:

  • 使用 运行dom 数字设置 10,000 行
  • 在一个单元格中设置公式 (B1) =Sum(A1:A10000)
  • select B1 并计算单元格

设置一个宏 - 下面是基于您上面的代码的快速而粗略的 - 通过使用适当限定的 运行ges 和 Option Explicit.

可能会更整洁
Sub TestNativeSpeed()
    Dim j As Long
    Dim t As Single
    t = Timer
    For j = 1 To 10000
        Range("B1").Dirty
    Next
    Debug.Print "Native Sum: ", Int(Range("B1").Value), Timer - t
End Sub

我使用公式 =Rand() 设置了我的单元格并得到了结果(仅限单个 运行):

Native Sum: 4990 16.53125

我仅将它们重置为值(与您的代码一致)并且我得到了结果(仅 运行):

Native Sum: 4990 1.765625

我运行你的代码并得到了(仅运行):

Array: 4917 4.386719

Sum: 4917 27.73438

以上显示的是原生 Excel 通常是最快和最有效的方法。但是数组(不需要在 VBA 和 Excel 模型之间切换)在效率方面是次要的。