Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: How to swap scalar values without copies

by asarih (Hermit)
on Feb 19, 2004 at 23:47 UTC ( #330408=note: print w/replies, xml ) Need Help??


in reply to How to swap scalar values without copies

Is this not what you need?
$a=\$x; $b=\$y; print "$a $b\n" ($a,$b)=($b,$a); print "$a $b\n";

update: changed $a and $b to references.

Replies are listed 'Best First'.
Re: Re: How to swap scalar values without copies
by Anonymous Monk on Feb 19, 2004 at 23:57 UTC
    No, this violates the no-copy rule. If $a is a 10Mb string instead of 'a', then, during the assignement ($a,$b)=($b,$a) the process allocates 10 more Mb. I have verified the following resident memory counts:
    print "stage 0\n"; sleep 5; # memory usage now: 1800 Kb $a='a' x 10000000; $b='b'; print "stage 1\n"; sleep 5; # memory usage now: 21336 Kb ($a,$b)=($b,$a); print "stage 2\n"; sleep 5; # memory usage now: 31104 Kb
      One method I think possible is at the XS level. A simple scalar is stored as SvPV internally by Perl, which looks like this:
      SV xpv +--------+ +-----+ | ANY |--->| PVX |---> char[] | REFCNT | | CUR | | FLAGS | | LEN | +--------+ +-----+
      To do an immediate swap without copying strings, at XS level, do this -
      SV xpv +--------+ +-----+ | ANY |-+ ->| PVX |---> char[] | REFCNT | \ / | CUR | | FLAGS | \ / | LEN | +--------+ \/ +-----+ /\ SV / \ xpv +--------+ / \ +-----+ | ANY |-+ ->| PVX |---> char[] | REFCNT | | CUR | | FLAGS | | LEN | +--------+ +-----+

      I can provide an XS example if you are not sure how to do this at XS level.

        I think that Data::Swap does exactly this. The Swap.xs file, once stripped of all checks, looks like:
        #include "EXTERN.h" #include "perl.h" #include "XSUB.h" MODULE = Data::Swap PACKAGE = Data::Swap void swap(foo, bar) SVref foo SVref bar PREINIT: void *any; U32 flags; CODE: any = foo->sv_any; flags = foo->sv_flags; foo->sv_any = bar->sv_any; foo->sv_flags = bar->sv_flags; bar->sv_any = any; bar->sv_flags = flags;

        But for this you need to translate the .xs into a .c, compile the latter and place the resulting shared object in blib somewhere in the hierarchy. And you need also a Swap.pm module bootstrapping it.

        I would like to avoid to ask people to install this module to run my code. Is it possible to hide these files in my user hierarchy?

        I begin to believe that there is no native way to solve my original problem in Perl5.

Re: Re: How to swap scalar values without copies
by Anonymous Monk on Feb 20, 2004 at 00:06 UTC
    (I see now the update, and I don't know how to update my reply in turn ...).

    Swapping the values of the references does not waste memory, but it violates rule n.2, namely that I want $a to be a string, not a reference to a string.

      I don't think you can have it both ways. You either need to work around having a reference or live with the major memory requirement. I'm not an XS-guru, but it appears Data::Swap just does the reference stuff for you.

      ----
      : () { :|:& };:

      Note: All code is untested, unless otherwise stated

      That is a very stupid requirement. You're creating a problem where one doesn't exist.
        Thanks for your insightful contribution

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2022-08-13 12:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?