On May 26, 5:44 am, jason.li...@gmail.com (Xi Liu) wrote:
> I know I am doing the repetitive and useless summing again and again. What
> confuses me is that using the same algorithm, I mean
>
>  for my $i (99 .. 60000)
> {
>       my $sum;
>       map {$sum += $_->{foo_value}} @lines[$i - $n + 1 .. $i];
>       push @res, $sum;
>
> }
>
> in perl and
>
> for(int i =99; i <= 60000; i++)
> {
>       int sum = 0;
>       for(int j = i - n +1; j < i;  j++)
>           sum += lines[$j].foo_value;
>       res[i] = sum;
>
> }
>
> in c, there is a huge difference in efficiency.
> the c program,  even using the same stupid algorithm, the cost of time is
> acceptable. So I translated it to perl , and avoid the slow subscripting
> operations using map on sliced array, I suppose the perl program would be
> slower, but I don't predict such a huge difference, you don't even need a
> benchmark or profiling tool to notice the efficiency difference. This is
> what I am confused.
> Thanks for your patience!

I wrote and tested a version of your program that uses caching and
compared it to the non cached example you provided. The cached version
runs in about 3% of the time that the non cached version does. So, as
Uri observed, a better choice of algorithm can improve things quite a
bit. (Note, the cached version could also be implemented in the C
version.)

My run produced this output (timed using the Time::HiRes module).

C:\Old_Data\perlp>perl t.pl
cached: 0.0327188968658447 sums: 59902
non_cached: 1.18266701698303 sums: 59902


The program is:

#!/usr/bin/perl
use strict;
use warnings;
use 5.012;
use Math::Random::MT::Auto qw/ rand srand /; # or just use the built
in 'rand'
use Time::HiRes qw/ time /;                               # I just
like using a 'better' rand!
use List::Util qw/ sum /;
use Data::Dumper;

srand(1); # to get the same random numbers from run to run for
consistancy in timing
my @lines;
for (0 .. 60000) {
        push @lines, {foo_value => int(rand 100000)};
}

my $n = 100;
my ($start, $end) = (99, 60000);

my $begin = time;
my $sum = sum map $_->{foo_value}, @lines[ $start - $n + 1 ..
$start ];

my @res = $sum;

for my $upper ($start+1 .. $end) {
        $sum += $lines[$upper]{foo_value} - $lines[$upper - $n]{foo_value};
        push @res, $sum;
}
my $finish = time;

say "cached: ", $finish - $begin, " sums: " . @res;
#open FH, '>', 'cache.txt'; print FH Dumper \@res; close FH;
@res = ();

$begin = time;
for my $i (99 .. 60000) {
      push @res, sum map {$_->{foo_value}} @lines[$i - $n + 1 .. $i];
}
$finish = time;

say "non_cached: ", $finish - $begin, " sums: " . @res;
#open FH, '>', 'non_cache.txt'; print FH Dumper \@res; close FH;


Chris


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to