为何JavaScript中for循环首次执行callback时速度异常快?
为什么首次带空回调的循环执行远快于后两次?
这个现象的核心原因是V8引擎的即时编译(JIT)优化策略,具体拆解如下:
第一次调用
fn时,传入的是空回调函数() => {}:
V8的编译器会对这段代码做激进优化——空回调本身没有任何执行逻辑,编译器会直接把callback && callback(i)这行代码完全内联并消除,相当于整个循环只剩下纯计数逻辑(i++直到达到length),所以执行速度极快。同时V8会生成一个针对「传入该空回调」场景的优化代码版本。第二次调用
fn时,传入了一个全新的空回调函数:
JS里每个() => {}都是独立的函数引用,V8检测到当前传入的回调和第一次的不是同一个,之前的优化版本不再适用,就会**去优化(deoptimize)**之前的代码,重新编译一个能处理任意回调的通用版本。这个版本没法再做逻辑消除的激进优化,所以回到常规耗时。第三次调用
fn时,用的又是新的空回调:
直接复用第二次生成的通用版本,所以耗时和第二次接近。
而当移除第三个callback参数时,三次调用里callback都是undefined,V8会生成一个针对「无回调传入」的优化版本,三次调用都复用这个版本,所以执行时间几乎一致。
内容的提问来源于stack exchange,提问作者Matsuzaka
相关产品推荐
相关产品推荐

