【发布时间】:2011-12-23 04:00:48
【问题描述】:
我想知道是否有可能了解 V8 究竟是如何优化和内联事物的。
我创建了三个简单的test functions,它们都以度为单位计算角度的正弦值。我将它们全部放入闭包中,以便 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 在某个网页上究竟是如何优化功能的?
【问题讨论】:
-
我不确定 C 风格内联的概念是否适用于 JITed 虚拟机。我只是推测,但我怀疑 V8 将运行时优化应用于经常调用的函数,但可能很难预测。
-
@mikerobi:这可能是一个幼稚的问题 - 但不能像某种调试工具一样简单地查看 V8 在编译/优化/内联期间所做的事情吗?
-
这可能是可能的,但我怀疑 V8 开发团队以外的任何人都可以告诉你如何做。
-
好吧,例如 PyPy 的 JIT 具有广泛的日志记录,他们开始构建一个工具来查看代码经过的所有中间表示(Python 字节码、JIT IR、机器代码),所以这样的事情应该是可能的理论上。但我想这会变得更容易,因为 (1) 实际的 JIT 是机器生成的,(2) 它是一个跟踪 JIT。
-
V8 目前不执行持续传播。您还可以通过在循环中创建函数来惩罚 V8(多次调用设置):尝试修改后的测试用例 jsperf.com/optimizing-v8/2。它消除了新生成的闭包实例的多次重新优化引入的开销,并使画面更加清晰。
标签: javascript optimization google-chrome inline v8