You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Stas Bekman <st...@stason.org> on 2000/12/26 21:31:24 UTC

XMas printing benchmark

Something like half a year ago I've posted a benchmark of different
printing techniques. Only now I've absorbed all the comments and here
is a new benchmark based on these comments.

  use Benchmark;
  use Symbol;
  
  my $fh = gensym;
  open $fh, ">/dev/null" or die;
  
  my @text = (
    "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n",
    "<HTML>\n",
    "  <HEAD>\n",
    "    <TITLE>\n",
    "      Test page\n",
    "    </TITLE>\n",
    "  </HEAD>\n",
    "  <BODY BGCOLOR=\"black\" TEXT=\"white\">\n",
    "    <H1>\n",
    "      Test page \n",
    "    </H1>\n",
    "    <A HREF=\"foo.html\">foo</A>\n",
    "text line that emulates some real output\n" x 100,
    "    <HR>\n",
    "  </BODY>\n",
    "</HTML>\n",
  );
  
  my $text = join "", @text;
  
  sub multi{
    my @copy = @text;
    my_print($_) for @copy;
  }
  
  sub single{
    my $copy = $text;
    my_print($copy);
  }
  
  sub array{
    my @copy = @text;
    my_print(@copy);
  }
  
  sub ref_arr{
    my @refs = \(@text);
    my_print(@refs);
  }
  
  sub concat{
    my $buffer;
    $buffer .= $_ for @text;
    my_print($buffer);
  }
  
  sub my_join{
    my $buffer = join '', @text;
    my_print($buffer);
  }
  
  sub my_print {
    for (@_) {
      print $fh ref($_) ? $$_ : $_;
    }
  }
  
  timethese
    (100_000, 
     {
      join    => \&my_join,
      array   => \&array,
      ref_arr => \&ref_arr,
      multi   => \&multi,
      single  => \&single,
      concat  => \&concat,
     });
  
  timethese
    (100_000, 
     {
  'array  /b' => sub{my $ofh=select($fh);$|=0;select($ofh); array()  },
  'array  /u' => sub{my $ofh=select($fh);$|=1;select($ofh); array()  },
  'ref_arr/b' => sub{my $ofh=select($fh);$|=0;select($ofh); ref_arr()},
  'ref_arr/u' => sub{my $ofh=select($fh);$|=1;select($ofh); ref_arr()},
  'multi  /b' => sub{my $ofh=select($fh);$|=0;select($ofh); multi()  },
  'multi  /u' => sub{my $ofh=select($fh);$|=1;select($ofh); multi()  },
  'single /b' => sub{my $ofh=select($fh);$|=0;select($ofh); single() },
  'single /u' => sub{my $ofh=select($fh);$|=1;select($ofh); single() },
  'concat /b' => sub{my $ofh=select($fh);$|=0;select($ofh); concat() },
  'concat /u' => sub{my $ofh=select($fh);$|=1;select($ofh); concat() },
  'join   /b' => sub{my $ofh=select($fh);$|=0;select($ofh); my_join()},
  'join   /u' => sub{my $ofh=select($fh);$|=1;select($ofh); my_join()},
     });


Under Perl version 5.6.0 on Linux OS the first set of results is
(after sorting by CPU clocks):

  Benchmark: timing 100000 iterations of array, concat, multi, ref_array,
single...
     single:  6 wallclock secs ( 5.42 usr + 0.16 sys =  5.58 CPU) @
17921.15/s
       join:  8 wallclock secs ( 8.63 usr + 0.14 sys =  8.77 CPU) @
11402.51/s
     concat: 12 wallclock secs (10.57 usr + 0.31 sys = 10.88 CPU) @
9191.18/s
    ref_arr: 14 wallclock secs (11.92 usr + 0.13 sys = 12.05 CPU) @
8298.76/s
      array: 15 wallclock secs (12.95 usr + 0.26 sys = 13.21 CPU) @
7570.02/s
      multi: 38 wallclock secs (34.94 usr + 0.25 sys = 35.19 CPU) @
2841.72/s

I<single> string print is obviously the fastest, I<join>,
I<concatination of string>, I<array of references to string> and
I<array of strings> are very close to each other (the results may
change according to the length of the strings, and the I<print call
per string> is the slowest.

Now let's look at the same benchmark where the printing was either
buffered or not:

  Benchmark: timing 100000 iterations of ...
  single /b: 10 wallclock secs ( 8.34 usr + 0.23 sys =  8.57 CPU) @
11668.61/s
  single /u: 10 wallclock secs ( 8.57 usr + 0.25 sys =  8.82 CPU) @
11337.87/s
  join   /b: 13 wallclock secs (11.49 usr + 0.27 sys = 11.76 CPU) @
8503.40/s
  join   /u: 12 wallclock secs (11.80 usr + 0.18 sys = 11.98 CPU) @
8347.25/s
  concat /b: 14 wallclock secs (13.73 usr + 0.17 sys = 13.90 CPU) @
7194.24/s
  concat /u: 16 wallclock secs (13.98 usr + 0.15 sys = 14.13 CPU) @
7077.14/s
  ref_arr/b: 15 wallclock secs (14.95 usr + 0.20 sys = 15.15 CPU) @
6600.66/s
  array  /b: 16 wallclock secs (16.06 usr + 0.23 sys = 16.29 CPU) @
6138.74/s
  ref_arr/u: 18 wallclock secs (16.85 usr + 0.98 sys = 17.83 CPU) @
5608.52/s
  array  /u: 19 wallclock secs (17.65 usr + 1.06 sys = 18.71 CPU) @
5344.74/s
  multi  /b: 41 wallclock secs (37.89 usr + 0.28 sys = 38.17 CPU) @
2619.86/s
  multi  /u: 48 wallclock secs (43.24 usr + 1.67 sys = 44.91 CPU) @
2226.68/s

First, we see the same picture among different printing
techniques. Second we can see that the buffered print is always
faster. But only in the case where print is called for each short
string, it creates more or less significant difference.

Your comments are welcome.

_____________________________________________________________________
Stas Bekman              JAm_pH     --   Just Another mod_perl Hacker
http://stason.org/       mod_perl Guide  http://perl.apache.org/guide 
mailto:stas@stason.org   http://apachetoday.com http://logilune.com/
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/  



Re: XMas printing benchmark

Posted by Ask Bjoern Hansen <as...@valueclick.com>.
On Tue, 26 Dec 2000, Stas Bekman wrote:

> Your comments are welcome.

your benchmark shows that it is really hard to screw up so much that
it actually matters and that there *always* will be somewhere else in
the application where there's more performance to be won.

:-)


 - ask

-- 
ask bjoern hansen - <http://ask.netcetera.dk/>
more than 70M impressions per day, <http://valueclick.com>



Re: XMas printing benchmark

Posted by "Alexander Farber (EED)" <ee...@eed.ericsson.se>.
Ron Beck wrote:
> 
> Since when???
> 
> I've always done...
> print<<"end_o_doc";
> <form action="../scripts/pgr_req03.cgi" method="post">
...
> Problems with this???
> Ron

I mean indenting code, not data.

> "Alexander Farber (EED)" wrote:
> > Why? With <<HERE you can't indent your code:
> >
> >   my @text = (
> >     "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n",
> >     "<HTML>\n",
> >     "  <HEAD>\n",
> >     "    <TITLE>\n",
> >     "      Test page\n",

[OT] Here document indenting (Was: XMas printing benchmark)

Posted by Andrew Ho <an...@tellme.com>.
Hello,

DC>    (my $text =<<'    foo') =~ s/^\s+://mg;
DC>        :<h1>Hello, World!</h1>
DC>        :  <p><a href="http://foo.org/">I</a> am an indented link.</p>
DC>        :      <p>So am <a href="http://bar.org/">I</a>.</p>
DC>    foo
DC>    print $text;

This, and other methods (without the beginning colon, for example) are
discussed in recipe 1.11 of the Perl Cookbook.

If you just want to indent your code, and don't care about the indentation
of the HTML, you can do something less expensive (let's pretend the above
was in a loop, or had interpolated variables, in which case the regex
could be potentially expensive):

    print<<"    EndHTML";
        <p>This HTML code will appear indented in the output.
         But, the ending delimiter can also be delimited, yay.</p>
    EndHTML

The only bad thing is that you have to count spaces carefully. Also if you
DO indent your HTML (pretty rare as I've observed in dynamically generated
pages that aren't templatized), you get slightly ugly code like this:

    print<<"    EndHTML";
  <p>The HTML I'm outputting dictates that this &lt;p&gt; appears at
   the indent level shown here. This makes my code ugly.</p>
    EndHTML

That's still better IMO than this:

    print<<EndHTML;
  <p>The HTML I'm outputting dictates that this &lt;p&gt; appears at
   the indent level shown here. This makes my code ugly.</p>
EndHTML

Because the latter totally destroys your identation.

FWIW, Ruby (http://www.ruby-lang.org/) has a nice abbreviation for the
indented delimiter--if you use an end token with a prepended hyphen, it
lets you indent the end token. Example:

    print <<-EndHTML
        <p>This HTML code will appear indented in the output.
         In Ruby, this is slightly neater than the equivalent
         Perl syntax.</p>
    EndHTML

This would be a great feature to port to Perl; it eliminates the tedious
"how many spaces did I indent?" problem which results in a "Can't find
string terminator..." error. Oddly enough, Ruby will complain, though, if
you omit the space between the print and the <<.

Humbly,

Andrew

----------------------------------------------------------------------
Andrew Ho               http://www.tellme.com/       andrew@tellme.com
Engineer                   info@tellme.com          Voice 650-930-9062
Tellme Networks, Inc.       1-800-555-TELL            Fax 650-930-9101
----------------------------------------------------------------------


Re: XMas printing benchmark

Posted by darren chamberlain <da...@boston.com>.
How about this:

### Code:
    (my $text =<<'    foo') =~ s/^\s+://mg;
        :<h1>Hello, World!</h1>
        :  <p><a href="http://foo.org/">I</a> am an indented link.</p>
        :      <p>So am <a href="http://bar.org/">I</a>.</p>
    foo
    print $text;

### Output:
<h1>Hello, World!</h1>
  <p><a href="http://foo.org/">I</a> am an indented link.</p>
      <p>So am <a href="http://bar.org/">I</a>.</p>

(darren)

> The only thing you _MUST_ have in column 1 is the "end_o_doc" indicating
> the end of the text.
> 
> Problems with this???
> Ron
> 
> 
> "Alexander Farber (EED)" wrote:
> > 
> > Perrin Harkins wrote:
> > > I know it's not the point, but I'd consider it poor style if I saw someone
> > > using anything other than a <<HERE doc for the job you're testing.
> > 
> > Why? With <<HERE you can't indent your code:
> > 
> >   my @text = (
> >     "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n",
> >     "<HTML>\n",
> >     "  <HEAD>\n",
> >     "    <TITLE>\n",
> >     "      Test page\n",

-- 
Eschew obfuscation.

Re: XMas printing benchmark

Posted by Ron Beck <rb...@tqtx.com>.
Since when???

I've always done...
print<<"end_o_doc";
<form action="../scripts/pgr_req03.cgi" method="post">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
  <td colspan="4">
    <div align="left">
      <font face="Arial" size="4" color="#800000">
       <strong>Individual Requesting the Service:</strong>
      </font>
      <br>
      <font face="Arial" size="2" color="#ff0000">
       <em>(Person filling out this form)</em>
      </font>
    </div>
  </td>
</tr>
<tr>
  <td>Requestor's Name</td>
  <td><input type="text" name="req_name" 
             value="$ldap_requestor{'fullname'}"></td>
  <td>Requestor's Employee #</td>
  <td><input type="text" name="req_empno" 
             value="$ldap_requestor{'uid'}"></td>
</tr>
<tr>
  <td>Requestor's Phone</td>
  <td><input type="text" name="req_phone" 
             value="$ldap_requestor{'telephonenumber'}"></td>
  <td>Requestor's E-mail Address</td>
  <td><input type="text" name="req_email" 
             value="$ldap_requestor{'mail'}"></td>
</tr>
end_o_doc
;

which works quite nicely and provides a very neat and indented source
page.  It also allows me to use quotes without an escape character.

The only thing you _MUST_ have in column 1 is the "end_o_doc" indicating
the end of the text.

Problems with this???
Ron


"Alexander Farber (EED)" wrote:
> 
> Perrin Harkins wrote:
> > I know it's not the point, but I'd consider it poor style if I saw someone
> > using anything other than a <<HERE doc for the job you're testing.
> 
> Why? With <<HERE you can't indent your code:
> 
>   my @text = (
>     "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n",
>     "<HTML>\n",
>     "  <HEAD>\n",
>     "    <TITLE>\n",
>     "      Test page\n",

Re: XMas printing benchmark

Posted by Perrin Harkins <pe...@primenet.com>.
On Fri, 29 Dec 2000, Alexander Farber (EED) wrote:
> Why? With <<HERE you can't indent your code:

Left-aligning the final line never really bothered me, since it doesn't
bother emacs.  To each their own I guess.  I find the HERE doc to be one
of the nicest Perl idioms.

- Perrin



Re: XMas printing benchmark

Posted by "Alexander Farber (EED)" <ee...@eed.ericsson.se>.
Perrin Harkins wrote:
> I know it's not the point, but I'd consider it poor style if I saw someone
> using anything other than a <<HERE doc for the job you're testing.

Why? With <<HERE you can't indent your code:

  my @text = (
    "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n",
    "<HTML>\n",
    "  <HEAD>\n",
    "    <TITLE>\n",
    "      Test page\n",

Re: XMas printing benchmark

Posted by Perrin Harkins <pe...@primenet.com>.
I know it's not the point, but I'd consider it poor style if I saw someone
using anything other than a <<HERE doc for the job you're testing.
- Perrin