On May 26, 5:44 am, [email protected] (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: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/