即使两行代码引用同一对象,编写额外的行来合并 With 和 End With 是否总是更快?
例如:
If Target.Column <> 1 Or Target.Row >= 100 Then Exit Sub
对比:
With Target
If .Column <> 1 Or .Row >= 100 Then Exit Sub
End With
这是否太过分了?
是否取决于代码本身来权衡两次引用对象与编写三行单独的行?或者写三行总是更快?
关于速度的问题 - 就处理速度而言,写这行代码的最佳方式是什么?即第二个测试是否更快地读为
> 99
比
>= 100
?
测试行号和列号的顺序有关系吗?
我已经测试了使用
With
与使用以下子命令在每个实例中引用 Range
对象的速度:
Sub WithSpeed()
Dim StartTime As Double
Dim SecondsElapsed As Double
Dim av As Double
Dim Target As Range
Dim i As Long, j As Long
'Remember time when macro starts
StartTime = Timer
Set Target = Sheet1.Cells(1, 1)
For j = 1 To 5
For i = 1 To 1000000
With Target
If .Column <> 1 Or .Row >= 100 Then Exit For
End With
Next i
av = av + Round(Timer - StartTime, 2)
Next j
'Determine how many seconds code took to run
Debug.Print 1, av / 5
End Sub
和
Sub NoWithSpeed()
Dim StartTime As Double
Dim SecondsElapsed As Double
Dim av As Double
Dim Target As Range
Dim i As Long, j As Long
'Remember time when macro starts
StartTime = Timer
Set Target = Sheet1.Cells(1, 1)
For j = 1 To 5
For i = 1 To 1000000
If Target.Column <> 1 Or Target.Row >= 100 Then Exit For
Next i
av = av + Round(Timer - StartTime, 2)
Next j
'Determine how many seconds code took to run
Debug.Print 2, av / 5
End Sub
结果:
first sub:
> 1 2.966
> 1 3.04
> 1 2.726
> 1 2.634
> 1 2.616
second sub:
> 2 2.924
> 2 2.708
> 2 2.506
> 2 2.496
> 2 2.724
每个子循环500万次。我将每个子程序运行了 5 次,每个子程序总共运行了 2500 万次循环。 500 万次循环后,子程序打印出 100 万次循环所花费的平均时间。
平均值:
1:2.80秒
2:2.67秒
我坚信这种差异可以忽略不计,并且可以归因于 PC 处理速度的偶然性。
当您开始在更多行中引用时,它可能很重要,但使用
With
不太可能对代码的速度产生很大影响。
我仍然强烈建议使用它,以提高代码可读性并防止输入错误。
首先,当然,更多的线路可以更快,很多。在那种情况下,你不会看到和感觉到任何差异,但至少你会养成一个习惯,总是这样开始。
我不确定 >99 和 =>100 的情况,但我认为 =>100 选项代码适用于 2 个条件 - 花费更多时间。
在 VBA 中,无论您的情况哪个条件优先。 VBA 正在检查这两个条件,即使第一个条件为真。差异将给出如下代码:
With Target
If .Column <> 1 Then Exit Sub
If .Row >= 100 then exit sub
End With
在这种情况下,顺序会产生影响,始终将更可能的情况放在第一位。
“with”的最大好处是将 if..end if、do...loop、select 等程序流程放入 with...end with 中。当使用笨重但内置的对象(例如 Recordset (DAO/ADODB) 或 Range (Excel))时尤其如此。
但是,我发现它会损害可读性,因此我避免将多个流程部分放在同一个 with 中,并且出于同样的原因我避免嵌套 with(尽管文档说它们有性能优势)。
块内部曾经也存在范围怪异,所以我不会在它们内部进行维度划分,尽管范围界定和垃圾收集似乎在过去几十年中已经得到解决。