Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re: interchanging variables the tough way (BENCHMARK)

by eduardo (Curate)
on Aug 30, 2000 at 19:56 UTC ( [id://30317]=note: print w/replies, xml ) Need Help??


in reply to interchanging variables the tough way

Ok, so as an update in benchmarking, I have written a quick benchmark of the 3 main swapping mechanisms I see written here. I also wanted to say, that the xor technique really just blew me away... never seen that before... anyways, here are some benchmarks:
#!/usr/bin/perl -w use vars qw/$a $b/; use strict; use Benchmark; $a = 0; $b = 1; sub traditional { my $c = $a; $a = $b; $b = $c; } sub arrays { ($b, $a) = ($a, $b); } sub xor { $a = $a ^ $b; $b = $a ^ $b; $a = $a ^ $b; } timethese(-5, { trad => \&traditional, arrays => \&arrays, xor => \&xor, }); [ed@ci478467-a ed]$ perl swap.pl Benchmark: running arrays, trad, xor, each for at least 5 CPU seconds. +.. arrays: 5 wallclock secs ( 5.12 usr + 0.00 sys = 5.12 CPU) @ 24 +242.19/s (n=124120) trad: 6 wallclock secs ( 5.00 usr + 0.01 sys = 5.01 CPU) @ 40 +630.74/s (n=203560) xor: 5 wallclock secs ( 5.11 usr + 0.00 sys = 5.11 CPU) @ 30 +829.16/s (n=157537)
so unfortunatelly, as amazingly cool as the XOR swap is, it seem slike it is slighly slower in perl than just using 3 variables... curses :)

Replies are listed 'Best First'.
RE: Re: interchanging variables the tough way (BENCHMARK)
by ncw (Friar) on Aug 30, 2000 at 20:09 UTC
    In ARM assembler the XOR method is actually equal in speed to the temporary variable method, and saves a register, and hence is a standard trick in any ARM programmers macro library. Eg :-
    ; Swap r0,r1 using r2 as temporary ; Takes 3 cycles traditional MOV r2, r0 ; r2 <- r0 MOV r0, r1 ; r0 <- r1 MOV r1, r2 ; r1 <- r2 ; Swap r0, r1 with no extra register ; Takes 3 cycles xor EOR r0, r0, r1 ; r0 <- r0 ^ r1 EOR r1, r0, r1 ; r1 <- r0 ^ r1 EOR r0, r0, r1 ; r0 <- r0 ^ r1
    Apologies for non perl post, but perspective can be useful sometimes ;-)
RE: Re: interchanging variables the tough way (BENCHMARK)
by turnstep (Parson) on Aug 30, 2000 at 20:18 UTC

    Note that XOR will not work properly in at least three cases: if the variable is a large value, a reference, or is undefined. The other two methods handle all three without a problem. (although -w will complain about the undef). Just something to watch out for.

    sub xor { $a = $a ^ $b; $b = $a ^ $b; $a = $a ^ $b; } @foo= qw(bar none at all); $a=999999999999; $b=8888888; print "BEFORE: A=$a B=$b\n"; &xor(); print "AFTER: A=$a B=$b\n\n"; $a=\@foo; $b=8888888; print "BEFORE: A=$a ($a->[0]) B=$b\n"; &xor(); print "AFTER: A=$a ($a->[0]) B=$b\n\n"; $a=undef; $b=8888888; print "BEFORE: A=$a B=$b\n"; &xor(); print "AFTER: A=$a B=$b\n\n"; ## Running the above produces: BEFORE: A=999999999999 B=8888888 AFTER: A=8888888 B=4294967295 BEFORE: A=ARRAY(0x87650a4) (bar) B=8888888 AFTER: A=8888888 () B=141971620 BEFORE: A= B=8888888 AFTER: A=8888888 B=0
      You can get the xor method to work on large numeric values by changing the swap function to stringify the values first:
      sub xor { $a = "$a" ^ "$b"; $b = "$a" ^ "$b"; $a = "$a" ^ "$b"; } $a=999999999999; $b=8888888; print "BEFORE: A=$a B=$b\n"; &xor(); print "AFTER: A=$a B=$b\n\n";
      output
      
      BEFORE: A=999999999999 B=8888888
      AFTER:  A=8888888 B=999999999999
      

        Though this adds trialing nulls ("\0") to whichever string is shorter. ):

                - tye (but my friends call me "Tye")

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://30317]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2024-04-19 18:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found