我正在编写一个常数时间字符串比较函数(用于node.js),并希望禁用V8的优化编译器,仅针对此单个函数;使用命令行标志不可行。
我知道使用
是否有一种不可变(且记录在文档中)的方法来禁用V8的优化编译器?
示例函数:
我知道使用
with{}
(或try/catch)块将立即禁用优化编译器,但我担心这个“特性”(漏洞)将在未来版本中被修复。是否有一种不可变(且记录在文档中)的方法来禁用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;
}
}
这里有一个只是为了好玩的性能测试。
n
的情况下执行给定操作的次数。在你的情况下,这个操作将是字符比较。由于这将是更长字符串的长度,所以a
是常量并不重要,因为对于所有比a
更长的字符串,该函数的值将是b.length
。(由于存在无限数量的比a
更长的字符串和有限数量的比a
更短的字符串,我们可以在分析中忽略较短的字符串。) - millimoose.length
和max()
的开销,该函数也不会完全线性。 - millimoosea
是否为b
的前缀。(为了使这个比较成为常数时间,实际上你必须实现我提到的“优化”.) 同时将所有操作计入计数器是没有意义的。通常情况下,你会单独计算一个或几个“代表性”的操作实例。读取或写入输入元素(在你的情况下是字符)很常见,输入元素之间的比较也很常见。你可以安全地忽略常量开销。 - millimoose