Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

swapping vars, two ways, 2 results...

by Sihal (Pilgrim)
on Dec 18, 2002 at 22:41 UTC ( [id://220967]=perlquestion: print w/replies, xml ) Need Help??

Sihal has asked for the wisdom of the Perl Monks concerning the following question:

I tried the following thing: swap 2 vars this way:
($b,$a) = ($a,$b) ;
Other way:
my $tmp = $b ; $b= $a ; $b = $tmp ;
If doing this with 2 big vars ( my $a = "10"x10000 ; in a long loop ( 10000 iterations) I can see different results. Case 2, while taking more memory, is kinda faster. In particular it uses up way less cpu time, while case 1 takes a lot of user time. Can somebody explain this ?
also, if I do my ($b,$a) = ($a,$b) It is way faster... ????

Replies are listed 'Best First'.
Re: swapping vars, two ways, 2 results...
by pg (Canon) on Dec 18, 2002 at 22:47 UTC
    By doing
    my ($b, $a) = ($a, $b)
    you are not swaping, you simply defined another set of variables. Try this, it will clearly show you what happend, and why it is way fast:
    $a = 100; $b = 200; my ($a, $b) = ($b, $a); print $a, "\n"; #200 print $b, "\n"; #100 print $main::a, "\n";#100 print $main::b, "\n";#200
    Update:

    When you do:
    ($b, $a) = ($a, $b)
    You are not working against two scalars, in stead you are working against two arrays, and two scalars. Not that it is slow, I don't even think it take less memory as you thought. Although you are not using any temps, Perl is using.
      well it does use less memory, but that may be due to the length of the vars...
      Anyway, this was a kinda stupid post but I wanted to write it cause I saw in one of my team mates code that he would never swap perls way, but rather Cs way, using a temp var. I first thought why wrinting it Cs way when you can use a more compact form. But then I saw that in some case it was actually totally different both in terms of cpu usage and mem, hence the post.
      but why is it that much faster ?

        This ($a,$b) = ($b,$a); is notionally equivalent to

        { local @list; $list[0]=$b; $list[1]=$a; $a=$list[0]; $b=$list[1]; undef @list; }

        Instead of allocating one temprary scalar and doing 3 assignments, it is allocating a temporary list, performing 4 assignments and deallocating the list.


        Examine what is said, not who speaks.

Re: swapping vars, two ways, 2 results...
by jdporter (Paladin) on Dec 19, 2002 at 01:55 UTC
    Other way:
    my $tmp = $b ; $b = $a ; $b = $tmp ;
    Well, maybe you get different results because the above way is hosed. Hopefully it's just a typo, but you're assigning to $b in both the last two lines, and never assigning to $a.

    In any event, swapping "perl's way" is better, faster, cheaper, shorter, and preferable in every way.

    Any questions?

    jdporter
    ...porque es dificil estar guapo y blanco.

      "perl's way" is better(?), faster, cheaper, shorter(just), and preferable in every way(opinion?).

      c:\test>perl -MBenchmark=cmpthese my ($a,$b)=('a'x1000,'b'x1000); cmpthese( -10, { PERL=> sub{ ($a, $b) = ($b, $a); }, C => sub{ my $t=$a, $a=$b, $b=$t; }, XOR => sub{ $a^=$b^=$a^=$b; }, } ); ^Z Benchmark: running C, PERL, XOR, each for at least 10 CPU seconds... C: 10 wallclock secs (10.01 usr + 0.00 sys = 10.01 CPU) @ 19 +7752.07/s (n=1980487) PERL: 10 wallclock secs (10.30 usr + 0.00 sys = 10.30 CPU) @ 12 +1439.73/s (n=1250222) XOR: 10 wallclock secs (10.03 usr + -0.01 sys = 10.02 CPU) @ 33 +5113.02/s (n=3356492) Rate PERL C XOR PERL 121440/s -- -39% -64% C 197752/s 63% -- -41% XOR 335113/s 176% 69% -- c:\test>

      If performance isn't a concern I use list assignment, if it is, I'd use the XOR method.


      Examine what is said, not who speaks.

        If performance isn't a concern I use list assignment, if it is, I'd use the XOR method.
        Besides being obfuscatory, the XOR method only works on numbers or strings. It doesn't work on other things, like references and filehandles. The perlish method works on anything.

        jdporter
        ...porque es dificil estar guapo y blanco.

        XOR swapping of strings in perl is BAD. I think it's merlyn who refers to these things as bad memes?

        The reason is that if the strings are different lengths, you get subtly "broken" results...

        my ($a,$b)=("a","bb"); printf("/%s/ (%d bytes) /%s/ (%d bytes)\n",$a,length($a),$b,length($b) +); $a^=$b^=$a^=$b; printf("/%s/ (%d bytes) /%s/ (%d bytes)\n",$a,length($a),$b,length($b) +);'
        This results in:
        /a/ (1 bytes) /bb/ (2 bytes) /bb/ (2 bytes) /a/ (2 bytes)
        The unexpected "2 bytes" for /a/ occurs because the string is still 2 characters long, but the 2nd character is now null.

        This can (and will) trip you up later, because $b ne "a", even though they print the same.
        --
        Mike

        By the way, if the two vars are very differents sizes, Perl's way gets slower.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2025-03-26 08:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    When you first encountered Perl, which feature amazed you the most?










    Results (67 votes). Check out past polls.

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.