javascript - V8 究竟如何优化/内联?

标签 javascript optimization google-chrome inline v8

我想知道是否有可能了解 V8 究竟是如何优化和内联事物的。

我创建了三个简单的test functions它们都以度为单位计算 Angular 正弦值。我将它们全部放入闭包中,以便 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 中内联如test2test3导致每秒的操作量完全相同。

另一方面,除法似乎没有优化(即预先计算),因为 test1明显更快。
  • 如果在这种情况下不手动进行,为什么不预先计算常数?
  • 是否可以看到 V8 究竟是如何在某个网页上优化功能的?
  • 最佳答案

    对您的第一个问题的有根据的猜测:

    严格来说,它不能恒定折叠 pi / 180部分,因为你不做 pi / 180在第二个和第三个函数中。你只需除(x * pi)通过 180 (乘法优先)。

    现在,你可能会问为什么它不改变操作的顺序来结束它可以优化的东西(这个过程称为重新关联,顺便说一句)......毕竟,结果是等价的(a * b / c = (a * b) / c) .数学是这样说的,对吧?

    好吧,数学是这样说的,但数学不使用浮点数。有了浮点数,事情就变得更复杂了。 x * pi可能会被四舍五入,然后重新排序会导致不同的结果。错误可能很小,但编译器优化的主要规则仍然是:你不能改变程序的结果。最好在以不幸的方式编写的一些数学基准上执行次优,而不是在某些图形代码中偏离一个像素(是的,这可能很明显)。

    关于javascript - V8 究竟如何优化/内联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8029106/

    相关文章:

    javascript - 在 JavaScript/Nodejs 中动态处理 undefined variable 的最佳实践

    r - 使用 lpSolve 在 R 中进行线性规划消除约束

    android - 在 Android 设备上的 google chrome 浏览器上从 node.js 服务器下载文件的错误

    javascript - 为 JavaScript 数组对象分配多个值

    javascript - "new"在 JavaScript 中仍然不推荐吗?

    javascript - 作为类的函数中的 return 语句

    c# - 领域与属性(property)。性能优化

    google-chrome - 如何设置 Chrome 的用户脚本版本号

    google-chrome - 使所有网站都可以使用 chrome 扩展

    javascript - Tslint 升级错误