如何禁用V8的优化编译器
我正在写一个常量string比较函数(对于node.js),并希望禁用V8的这个单一函数的优化编译器; 使用命令行标志是不可能的。
我知道使用with{}
(或try / catch)块会立即禁用优化编译器,但是恐怕这个“function”(bug)将在未来的版本中得到修复。
有没有一个不可变的(和文件)的方式禁用V8的优化编译器?
function示例:
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; } }
而性能testing只是为了好玩。
如果你想要坚实的方法来做到这一点,你需要使用--allow-natives-syntax
标志运行节点并调用它:
%NeverOptimizeFunction(constantTimeStringCompare);
注意你应该在调用constantTimeStringCompare
之前调用它,如果函数已经被优化了,那么这违反了一个断言。
否则with
声明是最好的select,因为使其优化将是绝对的疯狂,而支持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; }
仅仅提到声明会破坏整个包含函数 – 优化是在函数级粒度上完成的,而不是按照语句执行。
要真正检查是由特定的Node.js版本优化的function,你可以参考蓝鸟优化杀手维基。
我在节点7.2上检查了3个解决scheme:
-
with({})
– function被TurboFan优化 -
try {} catch(e) {}
– 函数被TurboFan优化 -
eval('');
– function没有优化
所以要保证禁用V8优化,你应该添加eval('')
到函数体。