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:[EMAIL PROTECTED]   http://apachetoday.com http://logilune.com/
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/  


Reply via email to