Email conversation
From | Robert de Bath |
To | Me |
Subject | Javascript XOR function on howtocreate |
Date | 9 May 2009 18:54 |
Just a little note about your different ways of doing a logical XOR,
your last version is
pretty reasonable but (using C) I prefer ..
if ( !!foo ^ !!bar ) { ... }
It actually says what you want to do.
I'll normally put some brackets in there too.
Robert de Bath
From | Me |
To | Robert de Bath |
Subject | Re: Javascript XOR function on howtocreate |
Date | 11 May 2009 09:36 |
Robert,
> if ( !!foo ^ !!bar ) { ... }
This works, but it's not an approach I would recommend, simply because it is
very wasteful. It would imply:
2 implicit casts to boolean
4 boolean NOT operations
2 implicit casts to number
1 bitwise XOR
1 more implicit cast to boolean
The !foo != !bar approach (while a little less obvious) implies:
2 implicit casts to boolean
2 boolean NOT operations
1 boolean != operation
The performance of the !foo != !bar approach is far better than the
performance of the !!foo ^ !!bar approach. In Opera it is 1.2 times faster.
In Safari it is 1.3 times faster. In IE it is 1.3 times faster. In Firefox
it is over 7 times faster. All of them agree that the approach I currently
recommend is significantly faster than your suggestion.
In terms of readability, yours feels a little more obvious, since it does
indeed follow the "do what I am thinking" pattern. However, neither of them
is particularly easy to read, and both may require a comment to tell
yourself or others that the operation being performed is an XOR.
Mark 'Tarquin' Wilton-Jones - author of http://www.howtocreate.co.uk/
From | Robert de Bath |
To | Me |
Subject | Re: Javascript XOR function on howtocreate |
Date | 13 May 2009 06:02 |
Awww, that's a shame, they generate almost the same code in C where the
compiler notices that NOT NOT is NOP.
I do wonder what the results are with Google Chrome or the new firefox
engine though.
Robert.
From | Me |
To | Robert de Bath |
Subject | Re: Javascript XOR function on howtocreate |
Date | 13 May 2009 08:57 |
Robert,
> Awww, that's a shame, they generate almost the same code in C where the
> compiler notices that NOT NOT is NOP.
It will still require an extra cast in that case (from integer to boolean),
but a good compiler may well be able to optimise that too.
This difference with JavaScript is largely due to it being an interpreted
language. With a compiled language like C, the compiler can take as much
time as it wants, searching for optimisations, since it will only be
compiled once, then users get the precompiled binary.
With interpreted languages, there is no such luxury. Browsers must interpret
huge amounts of code in a really small amount of time. Some Web pages use
several MB of code, and have only a couple of seconds to interpret it.
Browsers try many optimisations, but they are rarely smart. Compiling 1 MB
of C code on my computer would take far, far longer than a user would be
willing to wait for the same amount of code on a Web page.
They also cannot normally rely on variables holding specific types when the
code is executed, as they could change at any time, so they cannot optimise
away cast operations. That means that the !! is not a NOP in JavaScript,
since it still has to cast and invert.
> I do wonder what the results are with Google Chrome
The current recommendation is twice as fast as your suggestion.
> or the new firefox engine though.
The numbers I gave you were for the new engine. In the old engine, the
current recommendation is 1.8 times as fast as your suggestion.
Tarquin