You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Jim Serio <ji...@rollercoaster.com> on 2000/06/16 19:35:53 UTC

Slightly OT - Content-length

Since mod_perl and CGI scripts are dynamic, it seems that
Content-length has to be handled by the script. I'm curious
how some of you are handling this. It would seem to me that
you need to know all of your output before printing the first
line.

Jim

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


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

Posted by John Hughes <jo...@Calva.COM>.
> 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.


$r->print(\$var) (WAS: Re: Slightly OT - Content-length)

Posted by Ken Williams <ke...@forum.swarthmore.edu>.
perrin@primenet.com (Perrin Harkins) wrote:
>Incidentally, the $r->print() method conveniently lets you pass the string
>you want to send by reference.

I know this debate has been had before, but I think here's something new
to say.  I think this behavior is very strange, and actually
unnecessary.  It's unnecessary because in Perl *all* function arguments
are actually passed by reference, though we almost never notice (or
know) this.  For instance:

       {
         my $var = 7;
         &blah($var);
         print "$var\n";
       }

       sub blah { $_[0] = 9 }
       ---------------------------------
       Output: 9


It seems like $r->print() could easily take advantage of this behavior
just by being careful not to copy its arguments into new string
variables.  Then it would be unnecessary to ever pass by explicit
reference.

Just trying to make the point - I don't think it was made last time
around (and for some reason our list archive isn't searching recent
messages, so I couldn't actually check).


  -------------------                            -------------------
  Ken Williams                             Last Bastion of Euclidity
  ken@forum.swarthmore.edu                            The Math Forum



Re: Slightly OT - Content-length

Posted by Perrin Harkins <pe...@primenet.com>.
On Fri, 16 Jun 2000, Vivek Khera wrote:
> The other alternative is to generate your entire page as a string, get
> the string's length() and print that as your content-length header.

This is what I do, for two reasons.  First, most browsers give more
information to the user if you supply this, in the form of a progress bar
during downloads.  Second, if anything goes wrong during processing the
request I want to send out a user-friendly error page.  This is only
possible if you haven't sent any output yet.

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

- Perrin


Re: Slightly OT - Content-length

Posted by Vivek Khera <kh...@kciLink.com>.
>>>>> "JS" == Jim Serio <ji...@rollercoaster.com> writes:

JS> I too ignore this header but a system I'm integrating
JS> with that uses JSP to fetch data from an URL on my system
JS> aparently need to rely on the content-length. As for

But content-length is NOT a required header for HTTP protocol, is it?
If the program is relying on it, then it is broken and should be
fixed.

The other alternative is to generate your entire page as a string, get
the string's length() and print that as your content-length header.

Quite a lame thing to do on every page, if you ask me.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Vivek Khera, Ph.D.                Khera Communications, Inc.
Internet: khera@kciLink.com       Rockville, MD       +1-301-545-6996
GPG & MIME spoken here            http://www.khera.org/~vivek/

Re: Slightly OT - Content-length

Posted by Frank Wiles <fr...@wiles.org>.
 .------[ Jim Serio wrote (2000/06/16 at 10:35:53) ]------
 | 
 |  Since mod_perl and CGI scripts are dynamic, it seems that
 |  Content-length has to be handled by the script. I'm curious
 |  how some of you are handling this. It would seem to me that
 |  you need to know all of your output before printing the first
 |  line.
 |  
 `-------------------------------------------------

    The server handles this for you after the content is generated, by
    prepending that header to the output before sending it to the client
    broswer.  I might be wrong, but I am pretty sure that is how it
    works. 

 -------------------------------
  Frank Wiles <fr...@wiles.org>
  http://frank.wiles.org
 -------------------------------


Re: Slightly OT - Content-length

Posted by Vivek Khera <kh...@kciLink.com>.
>>>>> "JS" == Jim Serio <ji...@rollercoaster.com> writes:

JS> Since mod_perl and CGI scripts are dynamic, it seems that
JS> Content-length has to be handled by the script. I'm curious
JS> how some of you are handling this. It would seem to me that

How I handle it is to ignore it.  Nothing really breaks without it
other than keepalives are not done in Netscape.  No biggie for me,
since my static stuff is handled on other servers.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Vivek Khera, Ph.D.                Khera Communications, Inc.
Internet: khera@kciLink.com       Rockville, MD       +1-301-545-6996
GPG & MIME spoken here            http://www.khera.org/~vivek/