javascript - Why are two calls to string.charCodeAt() faster than having one with another one in a never reached if? - Stack Ove

I discovered a weird behavior in nodejschromev8. It seems this code:var x = str.charCodeAt(5);x = st

I discovered a weird behavior in nodejs/chrome/v8. It seems this code:

var x = str.charCodeAt(5);
x = str.charCodeAt(5);

is faster than this

var x = str.charCodeAt(5); // x is not greater than 170
if (x > 170) {
  x = str.charCodeAt(5);
}

At first I though maybe the parison is more expensive than the actual second call, but when the content inside the if block is not calling str.charCodeAt(5) the performance is the same as with a single call.

Why is this? My best guess is v8 is optimizing/deoptimizing something, but I have no idea how to exactly figure this out or how to prevent this from happening.

Here is the link to jsperf that demonstrates this behavior pretty well at least on my machine:


Background: The reason i discovered this because I tried to optimize the token reading inside of babel-parser.

I tested and str.charCodeAt() is double as fast as str.codePointAt() so I though I can replace this code:

var x = str.codePointAt(index);

with

var x = str.charCodeAt(index);
if (x >= 0xaa) {
  x = str.codePointAt(index);
}

But the second code does not give me any performance advantage because of above behavior.

I discovered a weird behavior in nodejs/chrome/v8. It seems this code:

var x = str.charCodeAt(5);
x = str.charCodeAt(5);

is faster than this

var x = str.charCodeAt(5); // x is not greater than 170
if (x > 170) {
  x = str.charCodeAt(5);
}

At first I though maybe the parison is more expensive than the actual second call, but when the content inside the if block is not calling str.charCodeAt(5) the performance is the same as with a single call.

Why is this? My best guess is v8 is optimizing/deoptimizing something, but I have no idea how to exactly figure this out or how to prevent this from happening.

Here is the link to jsperf that demonstrates this behavior pretty well at least on my machine: https://jsperf./charcodeat-single-vs-ifstatment/1


Background: The reason i discovered this because I tried to optimize the token reading inside of babel-parser.

I tested and str.charCodeAt() is double as fast as str.codePointAt() so I though I can replace this code:

var x = str.codePointAt(index);

with

var x = str.charCodeAt(index);
if (x >= 0xaa) {
  x = str.codePointAt(index);
}

But the second code does not give me any performance advantage because of above behavior.

Share Improve this question edited Jan 13, 2019 at 19:12 danez asked Jan 13, 2019 at 7:23 danezdanez 1,7091 gold badge12 silver badges15 bronze badges 6
  • In Firefox your second option is faster then the first one (for Latin characters). Looks like something is buggy in V8. – Dmitry Commented Jan 13, 2019 at 8:24
  • Is it var or const? Is it charCodeAt or codePointAt? The snippets in your question and those in your jsperf screenshot do totally different things. – Bergi Commented Jan 13, 2019 at 9:57
  • Yes, var y = str; (where y is never used afterwards) can trivially be recognised as dead code, and so is the side-effect-free parison in the condition of an empty if statement. – Bergi Commented Jan 13, 2019 at 10:00
  • 2 If you are optimising babel-parser, then use that as a proper benchmark, instead of trying to do micro-benchmarks. – Bergi Commented Jan 13, 2019 at 10:01
  • Your first code block is a TypeError in any plying environment. You can't assign to a const other than in the (required) initializer. – T.J. Crowder Commented Jan 13, 2019 at 10:35
 |  Show 1 more ment

1 Answer 1

Reset to default 10

V8 developer here. As Bergi points out: don't use microbenchmarks to inform such decisions, because they will mislead you.

Seeing a result of hundreds of millions of operations per second usually means that the optimizing piler was able to eliminate all your code, and you're measuring empty loops. You'll have to look at generated machine code to see if that's what's happening.

When I copy the four snippets into a small stand-alone file for local investigation, I see vastly different performance results. Which of the two are closer to your real-world use case? No idea. And that kind of makes any further analysis of what's happening here meaningless.

As a general rule of thumb, branches are slower than straight-line code (on all CPUs, and with all programming languages). So (dead code elimination and other microbenchmarking pitfalls aside) I wouldn't be surprised if the "twice" case actually were faster than either of the two "if" cases. That said, calling String.charCodeAt could well be heavyweight enough to offset this effect.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744977205a4604218.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信