Ah yes, but don't forget that to get this speed, you are sacrificing 
memory.  You now have another locally scoped variable for perl to keep 
track of, which increases memory usage and general overhead (allocation 
and garbage collection).  Now, those, too, are insignificant with one 
use, but the significance will probably rise with the speed gain as you 
use these techniques more often...

  Issac


Stas Bekman wrote:

> 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.
>
> _____________________________________________________________________




Reply via email to