【问题标题】:Which if statement performs faster in VBA?哪个 if 语句在 VBA 中执行得更快?
【发布时间】:2017-10-10 12:50:29
【问题描述】:

在 VBA 中,以下哪个 if 语句会执行得更好?

上下文:我正在遍历工作表以查找条目。

if [condition1] and [condition2] and [condition3] then
    *do something*
end if

if [condition1] then
    if [condition2] then
        if [condition3] then
            *do something*
        end if
    end if
end if

我的直觉是第二个陈述,因为它只需要在进行下一次迭代之前检查一个初始条件,但这是这样吗? 另外,有没有更好的方法呢?

【问题讨论】:

  • 会表现得更好 - 你可以通过在两个语句周围包裹一个计时器并根据实际代码测试性能来实际测试这个:)。除此之外,考虑到伪代码,这个问题有点含糊,真正有帮助。
  • AFAIK,即使 first 为 false,第一个语句也会评估所有 3 个条件。因此,第二个语句应该更快。无论如何,这个问题应该在 CodeReview 上,而不是 SO。
  • 只是挑剔,但第一条语句不是有效的 VBA。
  • 我希望实际上两者之间没有区别。 Excel 应用程序处理其代码所花费的时间比 VBA 代码评估 If 所花费的时间要多几个数量级。
  • 有比迭代搜索或 .Find 方法更快的方法,this link 比较了 3 种方法。结论是使用数组是最好的方法。

标签: vba excel


【解决方案1】:

我们应该忘记小的效率,比如大约 97% 的时间:过早的优化是万恶之源。然而,我们不应该放弃那关键的 3% 的机会。

— 唐纳德·高德纳

假设所有条件都没有副作用,基本上可以归结为:

If True And True And False Then

那么你就想多了,很可能在没有任何有意义的性能提升的情况下过度优化。不要再试图从代码中榨取每一纳秒,而是编写易于阅读、维护、调试和扩展的代码:如果代码中的任何地方都存在性能瓶颈,那么它就不在这里。。 p>


上下文:我正在遍历工作表以查找条目。

看,遍历工作表以寻找条目 你的瓶颈。与工作表交互比与内存数组交互慢数百甚至数千倍。

所以是的,因为您正在编写昂贵的代码,缺少短路有所作为,但并不是因为短路更有效地使用布尔逻辑 - 它会产生 [潜在显着的] 差异,因为您将有条件地避免昂贵的工作表读取

如果这听起来自相矛盾,那你就没有明白我的意思:短路布尔逻辑对已经很高效的代码的性能影响在很大程度上是微不足道的

继续,尝试将您正在迭代的Range(您是使用For 还是For Each 循环?There's a massive difference between the two,取决于您在做什么)转储到二维数组中,然后使用For 循环对其进行迭代并查找您的条目。我保证比通过拆分条件来模拟短路所获得的任何东西都更显着的性能改进。

或者,也许重新评估您是否需要迭代任何东西。如果您正在寻找一个条目,并且根据您的数据的样子,您可以将“条件列”合并为一个并使用Application.WorksheetFunction.Match 来定位条目,而无需编写任何循环或条件.

【讨论】:

  • 您好,非常感谢您的深入解答。当您说“将条件列合并为一个”时,您的意思是对它们进行连接吗?我只是想知道它是否会起作用,因为我仍在使用 Match 在单元格中寻找特定的术语/值,对吗?所以即使我加入我的条件字段,我将如何使用 Match 在工作表中找到加入的术语/值?
  • 是的,你将它们连接起来。然后你以同样的方式连接你的查找值并匹配它。与任何多列 vlookup 相同..
  • 我明白,我想我可以在侧面的隐藏列中添加连接版本或作为一种唯一标识符。感谢您的帮助!
【解决方案2】:

link 可能会有所帮助。

通常,第二个会执行得更快,原因很简单:如果第一个条件失败,它不会检查其他两个。在第一种方法中,它必须评估所有三个条件。在其他编程语言中,您有短路,这是您在第二种方法中实现的(在 VBA 中必须这样做,因为没有短路)。

【讨论】:

    【解决方案3】:

    第二种格式将是更快的实现。

    通过在即时窗口中尝试以下命令,您可以看到 vba 不会短路评估:

    if 1=0 and 1/0 then ?"Short Circuit"
    if 1=1 or 1/0 then ?"Short Circuit"
    

    如果 vba 像其他一些语言一样运行,那么您将收到消息 Short Circuit 打印。相反,您会收到错误消息:

    当然,我建议您参考Mat's Muganswer,因为将范围读入内存比直接读取工作表要快得多。

    我将向您推荐我的 answer 以了解有关如何读取/写入数组和单元格的另一个问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-29
      • 1970-01-01
      • 2012-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多