Quantcast
Channel: Planet Object Pascal
Viewing all articles
Browse latest Browse all 1725

The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

Almost a year ago, a thread on “premature Delphi optimization” came by on G+ about this code:

procedure ExchangeInteger(var AValue1, AValue2: Integer);
begin
  AValue1 := AValue1 xor AValue2;
  AValue2 := AValue1 xor AValue2;
  AValue1 := AValue1 xor AValue2;
end;

I don’t think that was premature optimization, just some code from an old fart that had already been programming in the era where processors had reasons to use it:

Back then, the only efficient way to exchange two variables of the same data type was using the XOR swap algorithm.

Nowadays you have more options, and this is where the fun in that thread began, which I will show in a minute.

First a bit of history

The XOR swap algorithm was widely known in the 80s of last century and before, especially because the 6502 processor (oh the days of LISA Assembler) was vastly popular, as was the Z80. Together, they powered the majority of the home computers in the 70s and 80s.

Popular 6502 powered computers were Acorn Atom and BBC, Apple II series, Commodore PET and VIC-20 (the Commodore 64 ran on a 6510),  Atari 400/800/XL/XE.

Popular Z80 powered computers were Amstrad CPC, MSX, Exidy Sorcerer,  TRS-80, P2000, Sinclair ZX80ZX81 and ZX Spectrum, KayproOsborne 1 and the Z-80 SoftCard for Apple II.

So back-then you needed the XOR algorighm to do the exchange.

Now the fun part: more choice

Two more variations for the method were proposed.

The first one was to use the XCHG instruction, which has been there since the 8086.

There is even an XCHG EAX, EAX instruction with opcode $90, which is the same as NOP.

Stefan Glienke proposed it, as Delphi compiler adds a MOV with every XOR.

procedure ExchangeInteger(var AValue1, AValue2: Integer);
asm
  xchg ecx, [eax]
  xchg ecx, [edx]
  xchg [eax], ecx
end;

You’d think this is fast: assembler + tiny XCHG instruction. Well, don’t think, but measure: this one is slower, even on modern systems.

Eric Grange did notice the speed difference and came up with this one:

procedure ExchangeInteger(var AValue1, AValue2: Integer);
var
  tmp: Integer;
begin
  tmp := AValue1;
  aValue1 := AVAlue2;
  aValue2 := tmp;
end;

Stefan Glienke concluded: The xor version is faster than the xchg thing. And the version with tmp var is faster (with optimization on ofc).

Real conclusion

The real conclusion however was made by Kenneth Cochran:

I’d leave this one up to the compiler to optimize.

–jeroen

via: Stefan Meisner – Google+ – if premature optimization is the root of all evil then….


Filed under: Borland Pascal, Delphi, Delphi 1, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 3, Delphi 4, Delphi 5, Delphi 6, Delphi 7, Delphi 8, Delphi x64, Delphi XE, Delphi XE2, Delphi XE3, Development, History, Pascal, Software Development, Turbo Pascal, UCSD Pascal

Viewing all articles
Browse latest Browse all 1725

Trending Articles