1

Is there any difference between these two like one is faster or smaller? Benefit of using one over another?

Swapping using XOR operator

int a, b;
a ^= b ^= a ^= b;

Swapping using third variable

int a, b, temp;
temp = a;
a = b;
b = temp;
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Shubh
  • 79
  • 2
  • 7
  • 1
    Why not to look at it's disassembly and compare? – Eugene Sh. Aug 22 '16 at 14:24
  • 2
    You can only use the `xor` variant for integer types. – EOF Aug 22 '16 at 14:25
  • Benefit #1: swapping is more readable. – barak manos Aug 22 '16 at 14:27
  • Which one, @barakmanos? :-) – cesarse Aug 22 '16 at 14:28
  • @cesarse: Which one what? – barak manos Aug 22 '16 at 14:29
  • 5
    `a^=b^=a^=b;` - seems like UB to me. – Sergio Aug 22 '16 at 14:30
  • The idea is the xor swap doesnt require a third resource (register or memory location). That is the savings. And kinda cool, but unreadable if you dont comment nor know the trick – old_timer Aug 22 '16 at 14:30
  • 1
    @dwelch: That really depends on the underlying HW architecture. Theoretically, even `a+=1` might require a third resource (in order to keep the value of `a+1` before storing it into `a`). And in fact, I believe that `a^=b` requires a third resource on most HW architectures. – barak manos Aug 22 '16 at 14:33
  • @barakmanos: both are swapping... – cesarse Aug 22 '16 at 14:34
  • @cesarse:, Oh, right... Well, I was referring to the readable one, though I guess that's kinda chicken-egg paradox. – barak manos Aug 22 '16 at 14:34
  • @Serhio: it it UB. – Bathsheba Aug 22 '16 at 14:36
  • 2
    @ barak manos understood, implementation can do all kinds of things, optimization, etc. This is closed now but just with arm and gcc, the xors are optimized into three xors as desired, but there were two loads and two stores to get them into registers and back out. with the third variable method it ended up as one would hope into two loads and two stores with the registers swapped on the store, the temp variable optimized out when used as a local, when the temp variable is global then it costs you more. if everything is local then it is all dead code and gets optimized away – old_timer Aug 22 '16 at 15:16
  • Other architectures would have been fun to try as well... – old_timer Aug 22 '16 at 15:17
  • 1
    1. "kinda cool, but unreadable" kind of says it all. Code needs to be written for the next developer, who might not be as smart as you, to understand easily. Comments age badly. 2. Do not try to second guess the compiler and it's optimizer, you will probably loose. 3. [Donald Knuth](https://en.wikipedia.org/wiki/Donald_Knuth): The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming. – zaph Aug 22 '16 at 15:28

2 Answers2

7

(The behaviour of both of your snippets is undefined since you're reading uninitialised variables).

Don't ever use XOR swap.

  1. The way you have it (a^=b^=a^=b;) is actually undefined behaviour as you are modifying a variable more than once between sequencing points. The compiler reserves the right to eat your cat.

  2. Trust the compiler to make optimisations.

  3. It only works for integral types.

  4. It would fail if a and b refer to the same object: if you use this method for swapping objects passed by address e.g. void xorSwap(int *x, int *y), a correct implementation requires an if block.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
5

XOR swapping is not clear: most people won't understand what your code is doing, and it is considered to be cryptic.

Self-explaining code is always better to have, so unless there is a huge performance issue and benchmarking proves the xor method to be faster, prefer using a third variable.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
blue112
  • 52,634
  • 3
  • 45
  • 54