Why is bitwise-xor (^) faster than unequal (! =) Comparison in Firefox?

I read an article from another site ( Computer Science - Can You Prove The Minimum Possible Effectiveness? ) About suggesting minimum Big-O times for worst-case scenarios.

One of the answers corresponds to a length explaining the time required to compare binary values ​​(or similar).

And I, though for myself: why not bitwise operations?

And I did this mock code in Javascript:

console.time('^');
for(var i=0;i<1e5;i++)13^15;
console.timeEnd('^');

console.time('!=');
for(var i=0;i<1e5;i++)13!=15;
console.timeEnd('!=');

      

And I was very surprised!

Cycle using ^

(bitwise-xor) can be faster than 3ms !

How is this possible?

Why is bitwise-xor ( ^

) faster than not-equal ( !=

) compareisson?


Other possible information:

I've tested Firefox 34.0.5 on Windows 7 Home Premium x64.

I also tried this code in Opera 12.17 (x64) and Chrome 39.0.2171.95 and the behavior is almost similar, this is code using ^

faster than 80% tests.


Another surprise:

In php do the following:

$now=microtime(true);
for($i=0,$x=0;$i<1e6;$i++)$x+=13^15;
echo microtime(true)-$now,PHP_EOL;

$now=microtime(true);
for($i=0,$x=0;$i<1e6;$i++)$x+=13!=15;
echo microtime(true)-$now,PHP_EOL;

      

Shows exactly the same effect: ^

faster than !=

.
Using $x+=!13^15;

instead $x+=13^15;

runs faster 70% of the time.

I tested http://writecodeonline.com/php/ which is running PHP 5.3 on Linux x64.

This code has a suggestion from @AlexK., Following the comment:

13 ^ 15 is a constant noop, maybe its just optimized (try something efficient x + = 13 ^ 15;)

+3


source to share


1 answer


You bark the wrong trees.

On, say a 2GHz processor, ^ or! = Can be executed in a nanosecond or so. It takes 1ms to execute 1e6 of them, not 460ms. This tells me two things:

  • for

    takes a significant part of the time, and
  • JavaScript is interpreted as uncompiled.

Please note that translators do not necessarily spend time optimizing. A really good optimizer would turn for($i=0,$x=0;$i<1e6;$i++)$x+=13^15;

into $x = 2000000

. Obviously he didn't. Ok, it's hard to tell if he turned $x+=13^15

into $x+=2

.



Let's look at something else. At the machine level, or even at the line level, it is $x+=13!=15

harder than $x+=13^15

. Both include $x+=

, but 13^15

are the only operation, whereas 13!=15

(in this context!) They are two operations. Compare 13 and 15 for first !=

to get true, and then convert true to 1. There are many ways in hardware - most of them involve jumping, which is expensive. There are other methods that include multiple boolean / shift / etc instructions to avoid jumping.

Possibly 13!=15

slower. But you don't know how much because of the significant overhead of the for loop.

Does it matter anyway? Is there a situation where these two operations are interchangeable? You have not been compared with (13^15)!=0

that could be equivalent.

+1


source







All Articles