我正在编写一个常量字符串比较函数(对于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只是为了好玩。
答案 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个解决方案:
with({})
- 功能由TurboFan优化try {} catch(e) {}
- 功能由TurboFan优化eval('');
- 功能未优化 因此,为了保证禁用V8优化,您应该将eval('')
添加到功能体。