【发布时间】:2019-01-13 07:23:45
【问题描述】:
我在 nodejs/chrome/v8 中发现了一个奇怪的行为。看来这段代码:
var x = str.charCodeAt(5);
x = str.charCodeAt(5);
比这更快
var x = str.charCodeAt(5); // x is not greater than 170
if (x > 170) {
x = str.charCodeAt(5);
}
起初我虽然可能比较比实际的第二次调用更昂贵,但是当 if 块内的内容不调用 str.charCodeAt(5) 时,性能与单次调用相同。
这是为什么?我最好的猜测是 v8 正在优化/去优化某些东西,但我不知道如何准确地解决这个问题或如何防止这种情况发生。
这里是 jsperf 的链接,它至少在我的机器上很好地展示了这种行为: https://jsperf.com/charcodeat-single-vs-ifstatment/1
背景:我发现这一点的原因是我试图优化babel-parser 内部的令牌读取。
我测试过,str.charCodeAt() 的速度是str.codePointAt() 的两倍,所以我可以替换这段代码:
var x = str.codePointAt(index);
与
var x = str.charCodeAt(index);
if (x >= 0xaa) {
x = str.codePointAt(index);
}
但是由于上述行为,第二个代码没有给我任何性能优势。
【问题讨论】:
-
在 Firefox 中,您的第二个选项比第一个选项更快(对于拉丁字符)。看起来 V8 中有些问题。
-
是
var还是const?是charCodeAt还是codePointAt?您问题中的 sn-ps 和您的 jsperf 屏幕截图中的 sn-ps 做的事情完全不同。 -
是的,
var y = str;(其中y之后永远不会使用)可以被轻易地识别为死代码,在空if的情况下的无副作用比较也是如此声明。 -
如果您正在优化 babel-parser,则将其用作适当的基准,而不是 trying to do micro-benchmarks。
-
您的第一个代码块在任何合规环境中都是 TypeError。除了在(必需的)初始化程序中之外,您不能分配给
const。
标签: javascript performance v8