2015-11-07 49 views
2

好吧,虽然我嵌套一些验证,如果,我已经谈到性能。什么是更快?两个比较或一个比较与一个逻辑检查?

让我们假设我验证票的节目,我可以做这样的事情:

var validateVipTicket = function (ticketInfo) { 
    if (ticketInfo.isPaid) { 
    if (ticketInfo.isOver16) { 
     if (ticketInfo.isVip) { 
     return true; 
     } else return 'Not Vip'; 
    } else return 'Not old enought'; 
    } else return 'Need to pay first'; 
}; 

,并调用它像这样validateVipTicket({isPaid: true, isOver16: true, isVip: true});

让我们假设并不重要指定发生了什么错误,我只是想要一个真或假,然后,什么方法会更快?

if (ticketInfo.isPaid) { 
    if (ticketInfo.isOver16) { 

OR

if (ticketInfo.isPaid && ticketInfo.isOver16) { 

第一种情况,第一个属性将被选中,当它完成,第二个属性将被检查。在第二种情况中,第一个属性将被检查,第二个属性将被检查,并且它们两个属性将相互比较。这是正确的吗?我错过了什么吗?哪个更快,为什么?

回答

1

这没有什么区别:

if (a && b) 

相同

if (a) 
    if (b) 

a && b的情况下,只要a发现错误,那么就什么都无所谓b是。

在两种情况下,CPU指令级会发生什么事是:

cmp [a], 0 ; a == 0? (it does this by calculating a - 0) 
jz false1 ; jump if result is zero 
; a is true 
cmp [b], 0 
jz false2 
; both a and b are true 

无论是3个不同的邮件将被退回,或仅有1,可以有所作为的速度,这取决于它是如何编译。在这个例子中,它没有什么区别:

false1: return "not a!"; 
false2: return "not b!"; 

just_false: return false; 

但在这里,转到涉及额外的跳/:

false1: result = "not a!"; goto done; 
false2: result = "not b!"; // goto done optimized away 
done: return result; 
+0

“CPU发生了什么”。好点子。低级别是一个很好的解释。 – Rodmentou

1

2条语句在性能上是等价的。在这两种情况下,第二次检查(ticketInfo.isOver16)仅在第一次检查(ticketInfo.isPaid)返回true时才被评估。这两种说法在速度上完全相同。所以你应该更喜欢那些对你更可读的。

1

现代JS引擎如V8的性能是相同的。尽管蹩脚的解释程序总是比其他程序执行得更好,但使用现代浏览器和JIT编译器(例如V8),您应该会得到相同的结果。

概念证明: http://jsperf.com/nested-conditionals-vs-inline

2

在第二种情况下,第一属性将被检查,第二 属性将被检查,并且它们,这两种性质进行比较 彼此抵靠。这是正确的吗?

不,这其实并不正确。 &&运算符执行short-circuit evaluation,这意味着如果第一个操作数计算结果为false,则不会评估第二个操作数。

这使得两种方法完全相同(即使有任何副作用评估的oparands)。由于他们以相同的方式完成相同数量的工作,因此可以预期性能非常相似。这些方法最终最终会生成相同的可执行代码。