9

I'm updating mootools from 1.3.2 to 1.4.1. I saw a strange change. From this

for (var i = 0, l = this.length; i < l; i++){....

to this

for (var i = 0, l = this.length >>> 0; i < l; i++){

how the ">>>" operator, used in that way, can improve performance? What do you think about it?

Dimitar Christoff
  • 26,147
  • 8
  • 50
  • 69
Antonio
  • 1,065
  • 3
  • 14
  • 27

4 Answers4

8

The >>> bitwise operator is bounded between and including 0 and 2^32-1 (4,294,967,295). By using using >>>, the framework ensures that the loop does not execute near-infitite times.

PS. The context of the code:

Array.implement({every: function(fn, bind){
    for (var i = 0, l = this.length >>> 0; i < l; i++){
        if ((i in this) && !fn.call(bind, this[i], i, this)) return false;
    }

Since i is initialised at zero, and incremented by an integer 1, and the length property is always an integer, there are no negative side-effects. Another application of the >>> method is rounding, to convert a decimal number to an integer.

Rob W
  • 341,306
  • 83
  • 791
  • 678
  • @Antonio Please remember to accept this answer by clicking the tick mark next to it if it solved your question :) – MattiSG Nov 24 '11 at 18:43
2

I guess the reason is some kind of conversion to make sure that the value is always numeric (as opposed to eg. the string '2').

erikkallen
  • 33,800
  • 13
  • 85
  • 120
1

Keeto from mootools team shed some light as to 'why' they do this, the answer is, generics and array-likes.

All array methods are supposed to also work as Array.every / Array.prototype.every calls. Which means, you can pass on an object with .length: -1 or similar.

This ensures the length will not be invalid for the loop to fail, I suppose.

Array.prototype.forEach.call({0:1, length: -1});
Dimitar Christoff
  • 26,147
  • 8
  • 50
  • 69
  • *"Keeto from ... and array-likes"* `[citation needed]`. That aside, `-1 >>> 0` equals `4,294,967,295`, which is not equal to the behaviour of a length of -1. The `(i in this)` part of the expression results in the desired effect, but looping 4.3E9 times to achieve the effect of `-1` is extremely inefficient. – Rob W Nov 27 '11 at 11:22
  • ok, bad example, this, neg values is one thing it won't work on. strings, null, even functions etc --> most will return 0 – Dimitar Christoff Nov 27 '11 at 21:34
0

I've seen this "bitshift by zero" technique used as a quick'n'dirty truncate method.

e.g.:

42.8989 >>> 0 == 42

however, this misappropriation of bitshifting might go seriously wrong if you feed in a negative number:

(-42.8989) >>> 0 == 4294967254 
spender
  • 117,338
  • 33
  • 229
  • 351