哪个功能是更快的Abs或IIf?

时间:2014-05-25 13:14:02

标签: sql vba

我运行了以下测试,以确定IIfAbs之间的效率差异:

Public Sub TestSpeed()
    Dim i As Long
    Dim res As Integer

    Debug.Print "*** IIF ***"
    Debug.Print Format(Now, "HH:mm:ss")
    For i = 1 To 999999999
        res = IIf(-1 = True, 1, 0)
    Next
    Debug.Print Format(Now, "HH:mm:ss")

    Debug.Print "*** ABS **"
    Debug.Print Format(Now, "HH:mm:ss")
    For i = 1 To 999999999
        res = Abs(-1)
    Next
    Debug.Print Format(Now, "HH:mm:ss")

End Sub

结果显示Abs的速度提高了约12倍:

TestSpeed
*** IIF ***
15:59:08
16:01:26
*** ABS **
16:01:26
16:01:37

任何人都可以支持这一点或证明相反的情况属实吗?

修改

可能需要在两个函数之间做出决定的一种情况是根据SQL查询中的条件执行多个计数,例如:

SELECT Sum(Abs(Colour = 'Yellow')) AS CountOfYellowItems, Sum(Abs(Votes>3) AS CountOfMoreThanThreeVotes FROM tblItems

SELECT Sum(IIf(Colour = 'Yellow' ,1 ,0)) AS CountOfYellowItems, Sum(IIf(Votes > 3 ,1 ,0) AS CountOfMoreThanThreeVotes FROM tblItems

1 个答案:

答案 0 :(得分:1)

我进行了类似的测试以支持您的发现:

Option Compare Database
Option Explicit

Public Sub SpeedTest()
    Const LoopLimit = 99999999
    Dim Tasked(LoopLimit) As Boolean, i As Long
    Dim Total As Long, t0 As Single, Elapsed As Single

    For i = 0 To LoopLimit
        Tasked(i) = False
    Next

    Debug.Print "*** IIF ***"
    Total = 0
    t0 = Timer
    For i = 0 To LoopLimit
        Total = Total + IIf(Tasked(i) = True, 1, 0)
    Next
    Elapsed = Timer - t0
    Debug.Print "Elapsed time: " & Format(Elapsed, "0.0") & " seconds."
    Debug.Print "Average time: " & Format(Elapsed / (LoopLimit + 1) * 1000000000, "0") & " nanoseconds."

    Debug.Print "*** ABS ***"
    Total = 0
    t0 = Timer
    For i = 0 To LoopLimit
        Total = Total + Abs(Tasked(i))
    Next
    Elapsed = Timer - t0
    Debug.Print "Elapsed time: " & Format(Elapsed, "0.0") & " seconds."
    Debug.Print "Average time: " & Format(Elapsed / (LoopLimit + 1) * 1000000000, "0") & " nanoseconds."
End Sub

导致

*** IIF ***
Elapsed time: 19.0 seconds.
Average time: 190 nanoseconds.
*** ABS ***
Elapsed time: 2.4 seconds.
Average time: 24 nanoseconds.

就原始执行速度而言,Abs(BooleanValue)似乎比IIf(BooleanValue = True, 1, 0)快一个数量级。

这种差异是否会对可能使用这些功能的代码的整体性能产生重大影响,这在很大程度上取决于上下文,如here所示。