【问题标题】:VBA: Why are For Each loops faster than For loops?VBA:为什么 For Each 循环比 For 循环快?
【发布时间】:2021-10-01 13:56:39
【问题描述】:

在 VBA 中,众所周知,For Each 循环将比 For 循环更快地遍历 Collection,两种循环方法之间的时间差异随着 @ 的函数呈指数增长(?) 987654325@ 大小。 (这当然假设迭代是“按顺序”在Collection 成员上进行的。)

为什么它会更快? For Each 循环如何比通过Collection 中的索引更快地访问项目?

【问题讨论】:

  • @GSerg 感谢您的链接。从那篇文章中,我找到了一个似乎详细介绍了 VBA 内部工作原理的网站,所以也许我可以在那里找到答案。

标签: vba performance for-loop foreach


【解决方案1】:

您认为For EachFor 1 To 快的假设是错误的。两者都循环通过一组数字,它们可以以相同的速度完成。

For Each 变体中,数字标识集合中的对象,例如 Sheets(1)、Sheets(2)、Sheets(3) 等。这些工作表不会在循环中加载甚至访问。它们只是被引用。

相比之下,For i = 1 to 3: Set Ws = Sheets(i) 只会创建对工作表的引用。

因此,不同之处在于您对引用对象的处理方式,而不是您引用它们的方式。 For Each 通常显示为更简单的代码。但是,如果您想参考ActiveSheet.Cells(3),您确实需要知道这将是 C1 还是 A3,并且明显更容易编码是以透明度为代价的。我将其视为品味问题。

Dim Arr As Variant
Dim R As Long
Arr = Range("A1:A20")
For R = 1 To UBound(Arr)
    Debug.Print Arr(R, 1)
Next R

快很多
Dim Rng As Range
Dim Cell As Range
Set Rng = Range("A1:A20")
For Each Cell in Rng
    Debug.Print Cell.Value
Next Cell

但这是因为第二个代码引用了工作表 20 次,而第一个 sn-p 则引用了一次。也许正是您一直在阅读的这种差异。

【讨论】:

  • 另请注意,在For Each Cell in Rng 中,没有指定顺序(也没有记录),并且可以按任何顺序引用单元格。
  • @Variatus 我理解您关于尽量减少 VBA 和工作表之间的交互次数的观点,但我的问题是关于纯 VBA:明确地Collections。我通过 Collection 使用这两种方法进行了测试迭代,包含 70,000 个项目。每个项目都被添加到总数中。 For EachFor 循环快大约 1000 倍(分别运行 22 毫秒和 22 秒)。
  • @TehDrunkenSailor 为了让您的测试对我的分析产生影响,我们应该查看集合的组成和添加的“项目”。您发现的差异是关于读取单元格并将其值添加到总计或读取数组之间的差异。因此,如果您测试了一组单元格,那么您的结果将证明For Each Cell In Range.Cells 创建了一个单元格值数组(看起来很奇怪)。这并不能证明该集合的访问速度更快。
  • @Variatus 抱歉,这次我会更清楚。我的测试没有以任何方式与 Excel 交互;它是纯 VBA。我在 VBA 中创建了一个包含 70,000 个项目(数字 1 到 70,000)的集合。 (不是单元格的集合。)然后,我遍历集合的每个成员并将成员的值添加到总数中。我使用For EachFor 循环进行了此迭代。由于两个循环都执行完全相同的任务,我想知道为什么一个循环能够比另一个更快地完成。
猜你喜欢
  • 1970-01-01
  • 2015-11-12
  • 1970-01-01
  • 1970-01-01
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
相关资源
最近更新 更多