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/