XOR Swap Algorithm
Another question on stack overflow was about swapping algorithms without using temporary variables. The most well known of these is the xor swap algorithm.
void xorSwap (int* x, int* y) {
if (x != y) { //ensure that memory locations are different
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
The test is to ensure that x and y have different memory locations (rather than different values). This is because (p xor p) = 0 and if both x and y share the same memory location, when one is set to 0, both are set to 0. When both *x and *y are 0, all other xor operations on *x and *y will equal 0 (as they are the same), which means that the function will set both *x and *y set to 0.
Mildly curious about the performance difference between a swap algorithm using xor and one using a temporary variable, I decided to put together a test program.
#include <stdlib.h>
#include <math.h>
#define USE_XOR
void xorSwap(int* x, int *y){
if ( x != y ){
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
void tempSwap(int* x, int* y){
int t;
t = *y;
*y = *x;
*x = t;
}
int main(int argc, char* argv[]){
int x = 4;
int y = 5;
int z = pow(2,28);
while ( z-- ){
# ifdef USE_XOR
xorSwap(&x,&y);
# else
tempSwap(&x, &y);
# endif
}
return x + y;
}
Using gcc and compiling without optimization and with no other flags set, the time for the function xorSwap was:
real 0m3.976s
user 0m3.960s
The time for the function tempSwap was:
real 0m3.659s
user 0m3.568s
When compiled with -Os, the time for the function xorSwap was
real 0m2.068s
user 0m2.048s
And the time for the function tempSwap was:
real 0m0.543s
user 0m0.540s
Which indicates that the compiler is able to do a lot more optimization of the standard swap, including removing the temporary variable entirely. Which is basically saying what everyone knew all along. Micro optimizations usually don't work, as the compiler knows more about producing code for target platform than anyone.