Just saw a great post over here: http://www.coldfusioncookbook.com/entry/53/How-do-I-determine-if-a-number-is-even-or-odd?
Actually, it was the first comment that was awesome. Were I to decide if a number is odd or even in ActionScript, I’d do the same thing the original post did (translated to AS):
iseven = ((num % 2) == 0)
The comment suggested a faster way using bitwise operators. Translated to AS it’s this:
iseven = ((num & 1) == 0)
Makes sense when you look at binary numbers:
001 = 1
010 = 2
011 = 3
100 = 4
101 = 5
Each of the odd numbers has a 1 in the far right column. The even numbers have 0 there. Mask it with “& 1” and you can see which it is.
A pretty minor difference syntactically, but bitwise operators are FAST. I’m not sure how mod (%) works internally, but I’d guess it does a fair amount of calculation.
Nice elegant solution.
Nice one! 😀
Hi Keith!
ohohhh I never thought I would once do something useful for you 🙂
I am such a fan of your book, and findings that I feel on fire 😉
small, but cool
I am happy
drop my comment, I am out 😉
That was my comment. What, no link to the original source? 🙂
Sorry Darron, I didn’t even notice who wrote it. And let me correct myself and point out that it was the SECOND comment that was so awesome.
Hear ye! Hear ye! Let it be known to all in the land that Darron Schall is master of all things bitwise!
🙂
Haha.. save that proclamation for when I show everyone what’s been up my sleeve for awhile… if I can ever finish it!
Brilliant! I’d been playing with modulo switching (on/off) in place of conditionals. Just replaced it with:
bitSwitch = (switchCount & 1);// bitwise switch
switchCount++;
Much thanks to Darron and Keith!
Yep, Darron is definitely bit wise! *Badabing* *Badaboom* Thank you, thank you!.. 🙂
iseven = !(num & 1)
at least on my machine
isEven = !(i%2)
takes 3/4ths the time of
isEven = !(i&1)
in action script 2. sad but true.
Actually on my machine, % and & are just about equal. 10000 iterations both give about 100 ms give or take 2 or 3 ms. I don’t know Darron, your crown may be in jeapordy.
OUTPUT:
Avg of 100 runs of 10000 iterations
& = 98.4444 ms
% = 97.295 ms
:-\.
Maybe it runs different on different versions of flash?
Hmm…
Where is Mike Lyda when you need him?
-Danny
From the Free On-line Dictionary of Computing:
OK now I’m really curious. Did you guys subtract the loop and assignment time? My benchmarking looked like this.
function test1() {
var isEven:Boolean;
var t1 = getTimer();
for (var i = 0; i!=100000; i++) {
isEven = !(false);
}
var t2 = getTimer();
for (var i = 0; i!=100000; i++) {
isEven = !(i%2);
}
var t3 = getTimer();
trace('% result: '+(t3-t2-(t2-t1)));
}
function test2() {
var isEven:Boolean;
var t1 = getTimer();
for (var i = 0; i!=100000; i++) {
isEven = !(false);
}
var t2 = getTimer();
for (var i = 0; i!=100000; i++) {
isEven = !(i & 1);
}
var t3 = getTimer();
trace('& result: '+(t3-t2-(t2-t1)));
}
test1();
test2();
test1();
test2();
% result: 79
& result: 41
% result: 78
& result: 39
the investigation continues…
flash 7
% result: 34, & result: 54, % result: 34, & result: 56
flash 8
% result: 40, & result: 31, % result: 39, & result: 31
On a machine code level, “& 1” is much faster than “% 2”. There is a machine opcode for bitwise and, which means it can happen in 1 cycle. There is no opcode for modulo, it’s going to take multiple cycles to get a value (modulo does repeated subtraction as far as I know). You’ll really notice the difference in large numbers. Imagine subtracting 2 from 1000000 (how many cycles is that?) vs 1 cycle for “& 1”.
So, if you’re not seeing any speed differences between the two, its probably the result of code in the Flash Player that isn’t optimizing the instruction. Might have something to do with coercing a variable to a number type which could be a long operation that negates the speed benefits of the fast “and”.
I suspect that ActionScript 3 does a better job at converting the “& 1” on the machine code level.