我想知道是否有可能了解V8如何进行优化和内联的详细信息。
我创建了三个简单的测试函数,它们都计算角度的正弦值。我将它们都放入闭包中,以便V8可以内联局部变量。
1. 使用预先计算好的常数Math.PI / 180
,然后执行Math.sin(x * constant)
。
我使用了这段代码:
var test1 = (function() {
var constant = Math.PI / 180; // only calculate the constant once
return function(x) {
return Math.sin(x * constant);
};
})();
2. 在程序运行过程中计算常量。
var test2 = (function() {
var pi = Math.PI; // so that the compiler knows pi cannot change
// and it can inline it (Math.PI could change
// at any time, but pi cannot)
return function(x) {
return Math.sin(x * pi / 180);
};
})();
3. 使用字面数字并在运行时计算常量。
var test3 = (function() {
return function(x) {
return Math.sin(x * 3.141592653589793 / 180);
};
})();
令人惊讶的是,结果如下:
test1 - 25,090,305 ops/sec
test2 - 16,919,787 ops/sec
test3 - 16,919,787 ops/sec
看起来pi
已经在test2
中被内联,因为test2
和test3
每秒完成相同数量的操作。
然而,除法似乎没有被优化(即预先计算),因为test1
速度显着更快。
- 如果不手动进行预计算,为什么常数没有被预计算?
- 是否可能查看V8如何在某个网页上精确优化函数?
setup
被多次调用),会对V8造成惩罚:请尝试修改后的测试用例http://jsperf.com/optimizing-v8/2。它消除了由多个闭包的新实例多次重新优化引入的开销,并使结果更加明确。 - Vyacheslav Egorov