I’m going to start posting some useful little bits of code up here as i think of them.
This is partly to help with my exceptionally poor memory, and partly to help out anyone who might be interested. I encourage anyone else who knows of some similar little helpful tips to send them to me and i’ll post them up here.
Ok, so here’s a nice simple one to start off. What’s an easy and simple method to determine if a number is odd or even?
The answer lies with the modulo operator (%) or the bitwise AND operator (&).
1 | i%2 |
Whatever i is, i%2 will evaluate to either 0 or 1.
Or a faster method for determining odd or even numbers would be the Bitwise AND operator (represented by a single ampersand: &):
1 | i&1 |
So what use is this?
Let’s say you’ve got a for loop:
1 2 3 4 5 6 7 | for(var i:int = 0; i < 50; i++){ if(i%2){ // Or i&1 //do something for odd numbers }else{ //do something else for even numbers } } |
So why would we use the modulo operator if a bitwise AND is faster?
To take this further, you could specify separate code for every nth number:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | for(var i:int = 0; i < 50; i++){ switch(i%4){ case 0: trace ("run every 4 iterations starting from 0"); break; case 1: trace ("run every 4 iterations starting from 1"); break; case 2: trace ("run every 4 iterations starting from 2"); break; case 3: trace ("run every 4 iterations starting from 3"); break; } } |
UPDATE
Some supporting code to show the speed difference.
Results in milliseconds:
Bitwise & : 2809
Modulo : 3456
Bitwise shift : 2801
Simple division : 2792
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | package { import flash.display.Sprite; import flash.utils.getTimer; public class SpeedTest extends Sprite { public function SpeedTest() { var bAndResult:int = ( runTest( bAnd, 10000000 ) ); trace("Bitwise & :", bAndResult); var modResult:int = ( runTest( mod, 10000000 ) ); trace("Modulo :", modResult); var shiftResult:int = ( runTest( bShift, 10000000 ) ); trace("Bitwise shift :", shiftResult); var divResult:int = ( runTest( div, 10000000 ) ); trace("Simple division :", divResult); } private function runTest( fnc:Function, count:uint ):int { var start:int = getTimer(); fnc( count ); return getTimer() - start; } private function bAnd( count:uint ):void { for( var i:uint = 0; i < count; ++i ) { var bleh:int = i & 1; } } private function mod( count:uint ):void { for( var i:uint = 0; i < count; ++i ) { var bleh:int = i % 2; } } private function bShift( count:uint ):void { for( var i:uint = 0; i < count; ++i ) { var bleh:int = i >> 1; } } private function div( count:uint ):void { for( var i:uint = 0; i < count; ++i ) { var bleh:int = i / 2; } } } } |
2 Comments
The compiler will usually optimize (among others) modulo 2 and divide by 2, so you can safely write what you mean in your code instead of making the code unreadable.
So it’s actually better to write x/2 instead of x >> 1 and x%2 instead of x&1.
That doesn’t seem to be the case for modulo and bitwise &. If you run a speed test, you’ll find that modulo is significantly slower than the bitwise &.
You could be right about the the >> and / 2 though. They seem to perform very similarly.