in reply to Re: How to swap scalar values without copies
in thread How to swap scalar values without copies

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

Replies are listed 'Best First'.
Re: Re: Re: How to swap scalar values without copies
by Roger (Parson) on Feb 20, 2004 at 00:24 UTC
    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.