【问题标题】:JavaScript: Is the `if / else` statement faster than the conditional statement in?JavaScript:`if / else` 语句是否比条件语句更快?
【发布时间】:2012-10-17 16:25:52
【问题描述】:

考虑以下两段代码:

var adj=0>grip.y?0<grip.x?0:-180:0<grip.x?-360:-180;

var adj;    
if (grip.y < 0) {   
    if (grip.x > 0)
        adj = 0;
    else
        adj = -180;
}
else {      
    if (grip.x > 0)
        adj = -360;
    else
        adj = -180;
}

它们都产生相同的结果,但哪个更快?

【问题讨论】:

  • 微优化,别费心了。如果您关心,请在 jsperf.com 上创建基准
  • 几乎没有区别,使用更易读的。
  • 您的第一个条件称为“三元”运算符。
  • 如果条件为真,它们都被实现为一个分支。性能上没有区别。但只有一个更容易阅读。猜猜是哪一个?
  • 第二个更易维护,应该优先。还可以考虑使用常量而不是硬编码数值,例如-360。例如,var CIRCLE_DEGREES = 360

标签: javascript performance if-statement conditional-statements micro-optimization


【解决方案1】:

速度差异可以忽略不计 - 使用您认为更方便和可读的任何一个。错误的条件构造不会有任何问题。

【讨论】:

  • 我知道两者之间也没什么区别,但我有兴趣优化 mousemove 事件处理程序,因此操作越少越好(显然)。
  • @AndreiOniga 我真的认为会有任何这样的区别。这完全取决于您的便利性。请通过此链接quirksmode.org/js/events_mouse.html。我会根据您的方便推荐 if else 或三元运算符。链接中也有一些示例(最后)可以回答您。 :)
  • 我承认在很多情况下我更喜欢使用 if...else 只是为了清楚起见。
【解决方案2】:

使用 switch 条件,比 if 和其他条件语句更快。

【讨论】:

    【解决方案3】:

    为了检查 JavaScript 的性能,我做了一个小实验。

    console.time("ternary operator");
    const val = (5 > 2) ? true : false;
    console.log(val);
    console.timeEnd("ternary operator");
    
    console.time("if condition");
    let val2;
    if (5 > 2) {
    val2 = true;
    } else {
    val2 = false;
    }
    console.log(val2)
    
    console.timeEnd("if condition");
    

    并且输出非常令人震惊,因为if 条件几乎比三元语句快两倍。

    结果:-

    所以总结一下,我建议在三元运算符上使用if 条件。

    【讨论】:

    • 您还为打印计时,这大大更昂贵,尤其是与在 JIT 期间应该优化的恒定条件相比。在第一次热身之后,第二次调用console.log 可能会快很多。 (如果是 Skylake 或更高版本的 CPU 可以在这段时间内做出反应,CPU 有机会提升到最大涡轮增压。)Idiomatic way of performance evaluation? 涵盖了这一点 - 尝试颠倒这两件事的顺序,看看它是否总是第二个更快。
    • 如果您想获得有意义的结果,您需要更复杂的测试。就像Why is processing a sorted array faster than processing an unsorted array? 一样,条件不是恒定的。
    • @PeterCordes 看来你是对的,我通常不会继续假设 CPU 处于那种情况或这种情况,我尝试多次运行程序(一个接一个)并观察输出数据并取其平均值,但看起来这一次当我尝试分别运行这两个程序以避免它们两个进程之间的任何冲突时,我发现两个数据几乎相似。感谢您让我再次研究这个问题,这打破了我的一个概念,即if 条件比三元运算符更快。谢谢
    • 取平均值是好的(或丢弃异常值并为每个版本采用最佳可重复时间)。但是,是的,如果您的方法有缺陷,那么您只是在重复同样的错误。微基准测试很难。仅对于运行时间足够长以隐藏测量/预热开销的事物而言,这很简单,即使那样,也可能无法测量您认为的结果,或者过度概括结果(例如吞吐量和延迟是不同的东西;有些方法的基准测试将取决于一个或另一个。)