### Re: How to swap scalar values without copies

by asarih (Hermit)
 on Feb 19, 2004 at 23:47 UTC 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.

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?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (2)
As of 2024-03-03 06:23 GMT
Voting Booth?
My favourite way to spend a leap day ...

Results (29 votes). Check out past polls.