Rob Nagler wrote:
> Perrin Harkins writes:
> Here's a fun example of a design flaw. It is a performance test sent
> to another list. The author happened to work for one of our
> competitors. :-)
>
>
> That may well be the problem. Building giant strings using .= can be
> incredibly slow; Perl has to reallocate and copy the string for each
> append operation. Performance would likely improve in most
> situations if an array were used as a buffer, instead. Push new
> strings onto the array instead of appending them to a string.
>
> #!/usr/bin/perl -w
> ### Append.bench ###
>
> use Benchmark;
>
> sub R () { 50 }
> sub Q () { 100 }
> @array = (" " x R) x Q;
>
> sub Append {
> my $str = "";
> map { $str .= $_ } @array;
> }
>
> sub Push {
> my @temp;
> map { push @temp, $_ } @array;
> my $str = join "", @temp;
> }
>
> timethese($ARGV[0],
> { append => \&Append,
> push => \&Push });
> <<
>
> Such a simple piece of code, yet the conclusion is incorrect. The
> problem is in the use of map instead of foreach for the performance
> test iterations. The result of Append is an array of whose length is
> Q and whose elements grow from R to R * Q. Change the map to a
> foreach and you'll see that push/join is much slower than .=.
>
> Return a string reference from Append. It saves a copy.
> If this is "the page", you'll see a significant improvement in
> performance.
>
> Interestingly, this couldn't be "the problem", because the hypothesis
> is incorrect. The incorrect test just validated something that was
> faulty to begin with. This brings up "you can't talk about it unless
> you can measure it". Use a profiler on the actual code. Add
> performance stats in your code. For example, we encapsulate all DBI
> accesses and accumulate the time spent in DBI on any request. We also
> track the time we spend processing the entire request.
While we are at this topic, I want to suggest a new project. I was
planning to start working on it long time ago, but other things always
took over.
The perl.apache.org/guide/performance.html and a whole bunch of
performance chaptes in the upcoming modperl book have a lot of
benchmarks, comparing various coding techniques. Such as the example
you've provided. The benchmarks are doing both pure Perl and mod_perl
specific code (which requires running Apache, a perfect job for the new
Apache::Test framework.)
Now throw in the various techniques from 'Effective Perl' book and voila
you have a great project to learn from.
Also remember that on varous platforms and various Perl versions the
benchmark results will differ, sometimes very significantly.
I even have a name for the project: Speedy Code Habits :)
The point is that I want to develop a coding style which tries hard to
do early premature optimizations. Let me give you an example of what I
mean. Tell me what's faster:
if (ref $b eq 'ARRAY'){
$a = 1;
}
elsif (ref $b eq 'HASH'){
$a = 1;
}
or:
my $ref = ref $b;
if ($ref eq 'ARRAY'){
$a = 1;
}
elsif ($ref eq 'HASH'){
$a = 1;
}
Sure, the win can be very little, but it ads up as your code base's size
grows.
Give you a similar example:
if ($a->lookup eq 'ARRAY'){
$a = 1;
}
elsif ($a->lookup eq 'HASH'){
$a = 1;
}
or
my $lookup = $a->lookup;
if ($lookup eq 'ARRAY'){
$a = 1;
}
elsif ($lookup eq 'HASH'){
$a = 1;
}
now throw in sub attributes and re-run the test again.
add examples of map vs for.
add examples of method lookup vs. procedures
add examples of concat vs. list vs. other stuff from the guide.
mod_perl specific examples from the guide/book ($r->args vs
Apache::Request::param, etc)
If you understand where I try to take you, help me to pull this project
off and I think in a long run we can benefit a lot.
This goes along with the Apache::Benchmark project I think (which is yet
another thing I want to start...), probably could have these two ideas
put together.
_____________________________________________________________________
Stas Bekman JAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide http://perl.apache.org/guide
mailto:[EMAIL PROTECTED] http://ticketmaster.com http://apacheweek.com
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/