How ~~ a.k.a double bitwise NOT operator in JavaScript can help boost performance of your app

Stas
2 min readMay 7, 2020

--

tl;dr;

~~ casts NaN, undefined, null, false, [], {} , “” and other falsey values to 0. It can also replace Math.floor() with ~~5.5 // 5. Rumor has it ~~ is faster than Math.floor() in some browsers.

Warning: ~~ will not work as a replacement of Math.floor()on an integer greater than 2147483647 or less than -2147483648 (max value for signed 32 bit integer).

!tl;dr;

~~ comes very handy when there is a need to increment something that can be undefined.
Let’s say we want to build a frequency table that shows how many times numbers appears in an array:

During the very first iteration n = 1, and such key “1” doesn’t exist in map yet, so its value is undefined. Thus, undefined + 1 // NaN. The same is happening during the second iteration, and then during the third: NaN + 1 is also NaN. So, resulting frequency table will look like:

To fix that, we would need to check for the value in map[n].

This is a one liner, but can we do better? Yes, with ~~!

Some naive tests with the average value of 10 runs on node v10.13.0

Math.floor(): 3.390ms

~~: 1.458ms

WOW! That’s more than 2x performance improvement!

Strict equality check (something === undefined): 0.994ms

~~: 0.866ms

and roughly 10% improvement here.

So, not only ~~ helps to write more concise code but also improves performance.

Let’s discuss here or tweet @kutyepov

As mentioned in the very beginning of the post, ~~ cannot be used with an integer greater than 2147483647 or less than -2147483648. This is due to fact that JavaScript is using 64 bits for number type and converts it to 32 bit to perform bitwise operations. I will go into detail on how bitwise operators work in on my next posts. Stay tuned.

--

--