Long ago, I was optimizing a hot-path in some game physics code which involved lots of Math.floor()
and parseInt()
operations. I came across a micro-optimization to cast float
or string
to int
.
~~ operation
console.log(~~1.6); // 1
What's happening?
A single ~
is a unary operator that converts the given number N
to -(N+1)
. For example:
console.log(~2); // -3
console.log(~1); // -2
console.log(~0); // -1
This operation is a bit too specific to be useful to many. But when you apply this operation twice, it's equivalent to Math.floor
or parseInt
. Examples:
console.log(~~-1); // -1
console.log(~~0); // 0
console.log(~~1); // 1
console.log(~~"-1"); // -1
console.log(~~"0"); // 0
console.log(~~2.4); // 2
console.log(~~3.9); // 3
console.log(~~"1"); // 1
console.log(~~true); // 1
console.log(~~false); // 0
Should I use it in my code?
It depends. As I said, it's a micro-optimization and the performance gains are only significant if you are doing this operation a lot in your code. Do not use it if you care about readability of your code as it might confuse other developers in your team.
Performance comparison
I wrote a little perf-test script to compare.
On Desktop Chrome, Math.floor()
is almost as fast as ~~
:
On Desktop Safari, ~~
is way faster than both Math.floor()
and parseInt()
:
On iPhone XS, ~~
is also way faster than the others:
Happy Coding!
Top comments (13)
Damn! I had not idea this was a thing!
Thanks for the great read! 🔥
Thanks!
That's a very interesting little thing. Do you happen to have any concrete data (or general idea) as to how much it improves performance?
(I'm not trying to contest your point, I'm just curious)
At the time I first found it, I do remember comparing perf and finding it faster.
I just wrote a quick perf test, see the updated article!
Cheers! That is a considerable increase from
parseInt
indeed!It is a good operator if you want a function that truncates toward zero.
Amazing article! Thank you
I've been using double tilde ocassionally for a while, but I never knew about the single one!
I think bitwise operations are always a bad idea.
If someone can't read it and guess what it does, then it shouldn't be used.
You are right. It depends, as I said.
I used it because of perf gains I needed. Maybe a comment explaining the code line would be a good compromise for situations like this.
Super interesting! Thank you for the read!
On Firefox, Math.floor is actually faster by 23%.
woah,
i'm down for using this.
besides, it's obviously faster.
thank you for this.