【问题标题】:Which is more efficient: assigning every time or checking?哪个更有效:每次分配还是检查?
【发布时间】:2021-11-25 17:08:37
【问题描述】:

假设您有一个变量ididit: mut bool,它控制某事是否已完成,以及一个可以完成该事的循环。出于可视化目的,这里有一些示例代码:

let mut ididit: bool = false;

for i in 0..SomeArbitraryValue {
    // do stuff
    if (conditions) {  // While certainly possible, this probably won't run every iteration.
        ididit = true;
    }
}

考虑到这一点,在分配之前检查ididit 是否已经为真会更有效吗?

换句话说,哪个更有效:检查冗余还是每次都分配?

【问题讨论】:

  • 先检查只会比不先检查慢,但在优化编译时可能没有任何区别。
  • 一般来说,回答性能问题的方法是衡量。
  • 在你的例子中,最好是在赋值ididit = true; break;之后打破循环,我们不需要继续检查其他条件。如果分配是一个大结构的克隆,那么之前检查会更好。
  • 像所有与性能相关的问题一样,这取决于。如果检查conditions 的成本很高(并且如果您在if 中没有做任何其他事情),那么首先检查ididit 可能会提高速度(例如if (!ididit) && conditions {…})。否则不检查可能会更快,但差异可能太小而无法衡量。
  • 只是为了检查我是否正确理解了这个问题:您正在将问题中的代码 if conditions { ididit = true; } 与 if conditions { if !ididit { ididit = true; } } 之类的代码进行比较。还是您将其与if !ididit { if conditions { ididit = true; } } 进行比较?我相信第一个和第二个变体的效率差不多,第二个变体可能会稍微慢一些(但由于优化器的魔力,它们可能会编译成相同的机器代码)。如果 conditions 的计算成本很高,则第三种变体可能会更有效。

标签: for-loop rust variable-assignment


【解决方案1】:

很大程度上取决于上下文。对于您的琐碎示例,Sven 说它可能会针对分配进行优化是正确的。但如果没有,您将花费额外的内存周期进行检查。即使它确实得到了优化,它仍然增加了必须维护的代码复杂性。如果您要处理更复杂的实体,情况可能会大不相同。

考虑在其他处理正在进行时读取值被延迟的情况,例如一个同步的 Web 访问,因为通常需要该值才能继续,并且在执行继续时写入只是被放入队列中。现在检查变得很昂贵,最好不检查就写。

现在考虑写入对象使其“变脏”并强制进行其他处理的情况。一个示例是将值绑定到显示的对象。分配给该值会变得非常昂贵,因为它涉及显示更新,而读取它却没有。显示更新是异步的,因此使用指标可能不会注意到它,但它会影响整个应用程序。所以在这种情况下,检查可能会好得多。这是一种需要认真思考的情况。

大多数情况下,您可以通过在考虑上下文的​​情况下仔细考虑来知道哪个更好。但是,如果您必须运行指标来确定哪个是哪个,通常最终差异很小,以至于不足以产生代码复杂性成本。您最终可能会过度优化您的应用程序,使其陷入无法维护的混乱局面。

【讨论】:

    猜你喜欢
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    相关资源
    最近更新 更多