DEV Community

Cover image for Clever coding tricks ( that we don't need )
Davide de Paolis
Davide de Paolis

Posted on

Clever coding tricks ( that we don't need )

Recently I was digging into some repository and my attention was caught by this code:

const nowInSeconds = ~~( / 1000)

What the heck are doing the tilde there?


I had to google it and of course ended up in Stack Overflow

The Tilde is the bitwise NOT operator

It behaves like that:

~N -> -(N+1)
Enter fullscreen mode Exit fullscreen mode

A couple of examples

~-2 --> 1
~2 --> -3
Enter fullscreen mode Exit fullscreen mode

Why the heck would i need something like this in a normal context?

yes.. i know that you can write clever hacks to convert falsy values or determine if you found something when using indexOf (~ -1 is 0, thus false)... but what are we even talking about?

You can use it, to convert any floating point number to a integer without performance overkill that comes with Math.floor(). Additionally, when you care about minification of your code, you end up using 2 characters (2 tildes) instead of 12. (from JS bitwise operators in practice)

Should we really use ~~(a/b) to avoid writing Math.floor(a/b)? Are you kidding me?

Honestly, when used in a normal application, in simple methods that are not running thousands of operation per second, it just hides the intention and hinders readability.
You might argue that it is just a matter of habit and I could be as well complain about the Spread Operator - in comparison to Object.assign:

const mergedOptions = {...optionsDefault, ...options};

const mergedOptions  = Object.assign({}, optionsDefault, options);
Enter fullscreen mode Exit fullscreen mode

and you might be true. But sorry, no, it is not the same thing.

These micro-optimisation using bitwise operator, are most of the time unnecessary tricks to look smarter during code reviews.

tell me again

Welcome to the cult

Just imagine this hypothetical conversation:

Oh, you really didn't know the double tilde? C'mon! it's a bitwise operation ( pronounced with low mysterious emphatic tone - welcome to the cult!) and it's sooo much faster than Math.floor.
Me: oh.. really? how much faster?
Up to 30% faster!!!
Me: wow, but, how much do we gain in milliseconds?
you can bring down 100000 operation from 44ms to 28s!!!!
Me: besides the fact who's gonna notice 20 milliseconds less in our application anyway, we are NOT running 100.000 operations! we are just running Math.floor ONCE at start-up!!! Get outta here!

I am not saying it is not useful. it definitely is, under some circumstances.
But as for any optimisation, we should do them when they are needed and they make sense.

Premature optimisation

Otherwise, keep it simple and favour readability.

some other useful resources about the topic:

Top comments (7)

mcsee profile image
Maxi Contieri • Edited

Premature Optimization is the root of all evil.

And a code smell.

I wil use (and quote) your article in my series

jonrandy profile image
Jon Randy πŸŽ–οΈ • Edited

It should be noted that ~~ is not the same as Math.floor - it simply removes the decimal part, and is consistently faster at doing so than Math.trunc - which is the normal suggested 'readable' way of doing so (at least in my tests - sometimes up to 50% faster):

Math.floor(2.1) // 2
~~ 2.1 // 2

Math.floor(-2.1) // -3
~~ -2.1 // -2
Enter fullscreen mode Exit fullscreen mode

It should also be remembered that performance is very important in some situations, and also that readability is purely subjective.

dvddpl profile image
Davide de Paolis

absolutely, very important in some situations, completely irrelevant in many others.
and also agree on the subjectivity of readability. but still prefer to read Math.floor than ~~

themanjia profile image

I agree on all the line with the sole exception for the "goes to" operator:

x = 10;
while (x --> 0) // While X goes to Zero
// Output: 9876543210
Enter fullscreen mode Exit fullscreen mode

The "goes to" operator is just very cool and works in almost every language!
(it's a "X minus minus major than 0" if someone didn't notice XD)

cicirello profile image
Vincent A. Cicirello

Thanks for giving me a new reason to add to my reasons that I dislike JS: allowing bitwise not on floating-point numbers.

willtrout profile image
Matt Willtrout

The compiler should optimize a double NOT to a NO-OP anyway.

webbureaucrat profile image

But it does do something in this context so that would be a bad optimization...?