如何禁用V8的优化编译器

时间:2013-08-27 22:17:42

标签: javascript node.js google-chrome v8 compiler-optimization

我正在编写一个常量字符串比较函数(对于node.js),并且想要为这个单一函数禁用V8的优化编译器;使用命令行标志是不可能的。

我知道使用with{}(或try / catch)块将禁用优化编译器 now ,但我担心这个“功能”(bug)将被修复未来的版本。

是否存在禁用V8优化编译器的不可变(并记录)方式?


示例功能:

function constantTimeStringCompare( a, b ) {
    // By adding a `with` block here, we disable v8's optimizing compiler.
    // Using Object.create(null) ensures we don't have any object prototype properties getting in our way.our way.
    with ( Object.create( null ) ){
        var valid = true,
            length = Math.max( a.length, b.length );
        while ( length-- ) {
            valid &= a.charCodeAt( length ) === b.charCodeAt( length );
        }
        // returns true if valid == 1, false if valid == 0
        return !!valid;
    }
}

perf test只是为了好玩。

2 个答案:

答案 0 :(得分:8)

如果你想要坚实的方法,你需要用--allow-natives-syntax标志运行节点并调用它:

%NeverOptimizeFunction(constantTimeStringCompare);

请注意,在调用constantTimeStringCompare之前应该调用它,如果函数已经优化,则会违反断言。

否则with声明是你最好的选择,因为它可以优化绝对疯狂,而支持try/catch则是合理的。但是,您不需要它来影响您的代码,这就足够了:

function constantTimeStringCompare( a, b ) {
    with({});

    var valid = true,
        length = Math.max( a.length, b.length );
    while ( length-- ) {
        valid &= a.charCodeAt( length ) === b.charCodeAt( length );
    }
    // returns true if valid == 1, false if valid == 0
    return !!valid;

}

仅提及with语句会破坏整个包含函数 - 优化是在函数级粒度下完成的,而不是按语句完成。

答案 1 :(得分:2)

要实际检查是否是特定Node.js版本优化的功能,您可以参考蓝鸟的Optimization Killers维基。
我在Node 7.2上检查了3个解决方案:

  1. with({}) - 功能由TurboFan优化
  2. try {} catch(e) {} - 功能由TurboFan优化
  3. eval(''); - 功能未优化
  4. 因此,为了保证禁用V8优化,您应该将eval('')添加到功能体。