You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by John Hughes <jo...@Calva.COM> on 2000/06/19 10:14:41 UTC

$r->print and references: Was RE: Slightly OT - Content-length

> Incidentally, the $r->print() method conveniently lets you pass the string
> you want to send by reference.

Why is that "convenient":

Fast:
	my $x = "fred" x 10000;
	$r->print $x;

More obscure and microscopicaly slower:
	my $x = "fred" x 10000;
	$r->print \$x;

(Hint - Perl passes all values by reference.  The point $r->print doing
an auto-dereference is supposed to be to let you pass a reference around
in *your* code.  Personaly I don't think this was a good idea.  If that's
what the user wanted he could have done it himself).

-- 
John Hughes <jo...@Calva.COM>, 
        CalvaEDI SA.                            Tel: +33-1-4313-3131
        66 rue du Moulin de la Pointe,          Fax: +33-1-4313-3139
        75013 PARIS.


Re: $r->print and references: Was RE: Slightly OT - Content-length

Posted by Perrin Harkins <pe...@primenet.com>.
On Mon, 19 Jun 2000, John Hughes wrote:

> > Incidentally, the $r->print() method conveniently lets you pass the string
> > you want to send by reference.
> 
> Why is that "convenient":

It's convenient for me because I have a scalar ref that I want to
print.  Maybe dereferencing it and passing by value wouldn't hurt anything
though.

> (Hint - Perl passes all values by reference.  The point $r->print doing
> an auto-dereference is supposed to be to let you pass a reference around
> in *your* code.

Right, that's what I'm doing.

- Perrin


RE: $r->print and references: Was RE: Slightly OT - Content-length

Posted by John Hughes <jo...@Calva.COM>.
De : Shane Nay [mailto:shane@isupportlive.com]
> To comment on what John originally said..., arg, here we go.  The
> difference between print \$somevariable, and print $somevariable can
> be very significant.

Nope.  Not "very".

> Everything is passed internally as a "reference", but that
> doesn't me it's done in the same way.  When you say "print $somevar",
> and "print \$somevar" two VERY different things happen. case 1:
> print $somevar  (I'm assuming a type of string)
> SV* somesv=(SV*)malloc(sizeof(SV));
> somesv->sv_any=(void*)malloc(sizeof(char*)*strlen(ourstring));
> //Notice, have to set aside memory
> strcpy((char*)somesv->sv_any,ourstring); //Notice we have to copy our data
> -->Call the "print function" and pass it a reference to "somesv"

I'm sorry, but I think you are simply wrong here.  If I call a perl
function or an XS routine with a variable as an argument it is passed by
reference.  There is *no* copy.

A simple proof:

	sub hack {
		$_[0] = 'a new string';
	}

	$a = 'an old string';
	hack $a;
	print $a;

This part of your pseudo code:

> SV* somesv=(SV*)malloc(sizeof(SV));
> somesv->sv_any=(void*)malloc(sizeof(char*)*strlen(ourstring));
> strcpy((char*)somesv->sv_any,ourstring); //Notice we have to copy our data

is *not* part of the call.  It's the code that puts a value in "somesv",
i.e.

	$somesv = "ourstring".

It is present in both the ref and the nonref cases.

Passing a refrence to $r->print is *slower*(by an infinitessimal amount).

The point of allowing it is to get around the problems with the normal
Perl coding style:

	sub slow {
		my $r = shift;
		my $arg = shift;       # A copy here!
		$r->print ($arg);
	}

But note the copy is not in the argument passing, it's in the Perl
code.

	sub fast_but_ugly {
		$_[0]->print ($_[1]);
	}

--
John Hughes <jo...@Calva.COM>,
        CalvaEDI SA.                            Tel: +33-1-4313-3131
        66 rue du Moulin de la Pointe,          Fax: +33-1-4313-3139
        75013 PARIS.


RE: $r->print and references: Was RE: Slightly OT - Content-length

Posted by Shane Nay <sh...@isupportlive.com>.
On Mon, 19 Jun 2000, you wrote:
> > De : Matt Sergeant [mailto:matt@sergeant.org]> 
> > On Mon, 19 Jun 2000, John Hughes wrote:
> > > (Hint - Perl passes all values by reference.
> > 
> > Are you sure thats the case with XS code?
> 
> Yes.

To expand on John's answer... :), and delve into where this thread started...:

In XS you just know how many variables are on the stack.  The only thing that
sits on the stack are pointers to SV's..., SV stands for "scalar value".  Now
as you might know, you can pass all sorts of things to XS functions, hashes,
arrays, etc.  So what happens is these things are "pushed" onto the stack of
execution, and the XS function is called.  It then peals things off of the
stack, and uses perl macros to find out what sort of reference it is.

To comment on what John originally said..., arg, here we go.  The difference
between print \$somevariable, and print $somevariable can be very significant. 
Everything is passed internally as a "reference", but that doesn't me it's done
in the same way.  When you say "print $somevar", and "print \$somevar" two VERY
different things happen.
case 1: print $somevar  (I'm assuming a type of string)
SV* somesv=(SV*)malloc(sizeof(SV));
somesv->sv_any=(void*)malloc(sizeof(char*)*strlen(ourstring)); //Notice, have
to set aside memory
strcpy((char*)somesv->sv_any,ourstring); //Notice we have to copy our data
-->Call the "print function" and pass it a reference to "somesv"

case2: print \$somevar
SV* somesv=(SV*)malloc(sizeof(SV)); //still need memory for this
somesv->sv_any=(void*)ourstring;
-->Call the "print function" and pass it a reference to "somesv"

Okay, so we need two less things to happen, we no longer need to set aside
memory for the string, and we don't have to copy it.  This is a big win in
terms of speed.  (Actually I think it happens quite a bit different internally,
but this is the "gist" of it.  There might even be one less SV malloc, because
it passes by "reference", it would have to create the reference which is an SV,
but it probably wouldn't have to create a second one like we need in case 1. 
Maybe Doug could help me out with this?)

So that's why when you pass by reference (and use it as such) it's 1) faster 2)
changes the value when it gets back to you, because it's not working from a
copy, it's working from the "real deal".  So if you're thinking of passing huge
strings, then it is in your best interest to pass by reference..., and if
you're passing hashes and arrays directly... SHAME ON YOU! :-) <Copying hashes
and arrays is NOT trivial... seriously>

Happy perling!
Shane.
(I tried to use less obfuscated c code..., sorry if I failed :-( )

RE: $r->print and references: Was RE: Slightly OT - Content-length

Posted by John Hughes <jo...@Calva.COM>.
> De : Matt Sergeant [mailto:matt@sergeant.org]> 
> On Mon, 19 Jun 2000, John Hughes wrote:
> > (Hint - Perl passes all values by reference.
> 
> Are you sure thats the case with XS code?

Yes.

-- 
John Hughes <jo...@Calva.COM>, 
        CalvaEDI SA.                            Tel: +33-1-4313-3131
        66 rue du Moulin de la Pointe,          Fax: +33-1-4313-3139
        75013 PARIS.


Re: $r->print and references: Was RE: Slightly OT - Content-length

Posted by Matt Sergeant <ma...@sergeant.org>.
On Mon, 19 Jun 2000, John Hughes wrote:

> (Hint - Perl passes all values by reference.

Are you sure thats the case with XS code? I don't personally know XS very
well, but there are some wierd things about it, and this might be one of
them. I know for certain that XML::Parser has a lot of slow-down because
of the Perl -> XS interface, and passing strings across it (although IIRC
Ilya did some work on that for perl 5.6).

-- 
<Matt/>

Fastnet Software Ltd. High Performance Web Specialists
Providing mod_perl, XML, Sybase and Oracle solutions
Email for training and consultancy availability.
http://sergeant.org | AxKit: http://axkit.org