XOR Swap
The XOR swap algorithm is an old programming trick. I’ve never personally seriously entertained using it, even in C, but myths abound that it is somehow faster than simple swapping via a temporary variable. Is it fast or just fancy?
As usual, I’ve put together a simple test to see if using XOR swap is any faster. Here it is:
package { import flash.display.*; import flash.utils.*; import flash.text.*; public class XORSwapTest extends Sprite { public function XORSwapTest() { var logger:TextField = new TextField(); logger.autoSize = TextFieldAutoSize.LEFT; addChild(logger); var i:int; // XOR swap is NOT faster and only works for integers const SWAP_REPS:int = 100000000; var a:int = 5; var b:int = 6; var temp:int; var beforeTime:int = getTimer(); for (i = 0; i < SWAP_REPS; ++i) { temp = a; a = b; b = temp; } logger.appendText("Assign swap time: " + (getTimer()-beforeTime) + "\n"); beforeTime = getTimer(); for (i = 0; i < SWAP_REPS; ++i) { a ^= b; b ^= a; a ^= b; } logger.appendText("XOR swap time: " + (getTimer()-beforeTime)); } } }
And here are the results I got:
Machine | Assign Swap Time | XOR Swap Time |
---|---|---|
3.0 Ghz Intel Core 2 Duo with 2GB RAM on Windows XP | 236 | 276 |
2.2 Ghz Intel Core 2 Duo with 2GB RAM on Mac OS X 10.6 | 321 | 368 |
At least in the case of AS3 on Flash Player 10, XOR swap is always slower than a regular swap via the assignment operator. Not only is the XOR swap slower, but it also only works with integers and is therefore less flexible and is an obscure technique so is less readable by others. So if you see anyone using a XOR swap in their AS3 code, kindly point them to this article. Of course, you should probably first remove any XOR swaps of your own!
#1 by grapefrukt on September 21st, 2009 ·
I think you should do a version with the temporary var instantiated inside the loop, i’m not able to test whether it would make any difference, but it should atleast make the comparison a bit more fair since that’s the normal use case.
But then again, since you’re doing a hundred million iterations normal might be a misnomer ;)
#2 by jackson on September 21st, 2009 ·
Good point. My reason for leaving out that case was to make sure I was testing just the swap algorithm and not the variable instantiation. But since you expressed interest and I never did the test, I figured I might as well:
On the same Windows machine, I’m getting nearly identical times to the other version with a temporary variable. I’ve run it a couple dozen times and the difference is +/- 2 ms.
Thanks for the suggestion!
#3 by grapefrukt on September 22nd, 2009 ·
Strangely I get these times in the standalone (release) player:
Assign swap (including instancing) time: 414
Assign swap time: 320
XOR swap time: 357
What really surprised me, even though I knew that the debug player is a bit slower, is that if i run it there (still the code compiled in release) I get these results:
Assign swap (including instancing) time: 890
Assign swap time: 790
XOR swap time: 625
That’s almost twice the execution time. I really need to set up my dev enviroment to launch both the debug and standalone players.
All this was run on my 2.2 Ghz Intel Core 2 Duo with 3.5GB RAM running Windows XP SP3
#4 by jackson on September 22nd, 2009 ·
Wow, those are some really surprising results! To test, I tried it out in the standalone players on the same Windows box as in the article and got this:
Those debug times look kind of crazy to me, but they are repeatable. The release times are pretty close to what I get with the browser plugin though. I wonder what accounts for our difference, especially since we have such similar machines.
Thanks for your comment and your result times.
#5 by skyboy on October 22nd, 2010 ·
Were you using an old version of the debug player? Those results look far too far apart, but in both tests XOR swap is faster in the debug player, which is probably where the people who use it got idea that three XOR and three assignments is faster than only three assignments.
#6 by jackson on October 22nd, 2010 ·
I always use the latest release player. At the time, that was Flash Player 10.0. Since I never test on a debug player, I didn’t know that XOR is faster there. Thanks for the explanation.
#7 by Bob on September 22nd, 2009 ·
There are some situations where the XOR swap is handy albeit not necessarily in actionscript. One particularly useful situation is in embedded systems where you do not have any room on the stack or heap to allocate a swap variable, so you are forced to do things the hard way.
On some architecture, xor swap is a lot faster than a temp var, but this is usually truer in the lower level systems (assembler etc).