in reply to perl process slower and slower when loop number increase
#! /usr/bin/perl use warnings; use strict; use Time::HiRes qw{ gettimeofday }; { my %remove; sub remove_later { undef $remove{$_[0]} ; $_[0] } sub remove_all { unlink keys %remove } sub create_file { my ($filename, $content) = @_; open my $out, '>', remove_later($filename) or die $!; print {$out} $content; } } sub measure { my ($command, $n, $prepare) = @_; # Switch the following two lines if you don't want to include comp +ilation. my $t0 = gettimeofday(); $prepare->() if $prepare; my @cmd = $command->($n); 0 == system @cmd or die $?; my $t1 = gettimeofday(); return $t1 - $t0 } { my %prepare = (java => \&_prepare_java, c => \&_prepare_c, erlang => \&_prepare_erlang, pascal => \&_prepare_pascal); sub prepare { my ($type, $n) = @_; sub { $prepare{$type}->($n) } if exists $prepare{$type}; } } sub _prepare_java { my ($n) = @_; create_file('Measure.java', << "__JAVA__"); class Measure { public static void main (String... args) { Integer i, s=0; for(i=0; i<=$n; i++){s+=i;} } } __JAVA__ 0 == system 'javac', 'Measure.java' or die $?; remove_later('Measure.class'); } sub _prepare_c { my ($n) = @_; create_file('measure.c', << "__C__"); int main () { int i = 0, s = 0; for(i=0; i<=$n; i++){s+=i;} return 0; } __C__ 0 == system 'gcc', 'measure.c' or die $?; remove_later('a.out'); } sub _prepare_erlang { my ($n) = @_; create_file('measure.erl', << "__ERLANG__"); -module(measure). -export([main/0]). main() -> sum(0,$n,0). sum(From,To,Sum) -> case From > To of false -> sum(From+1,To,Sum+From); true -> Sum end. __ERLANG__ 0 == system 'erlc', 'measure.erl' or die $?; remove_later('measure.beam'); } sub _prepare_pascal { my ($n) = @_; create_file('measure.pas', << "__PASCAL__"); var i,s:Int64; begin s:=0; for i:=1 to $n do s:=s+i; end. __PASCAL__ 0 == system 'fpc measure.pas &>/dev/null' or die $?; remove_later($_) for qw( measure measure.o ); } sub plot { my ($plot_file, @langs) = @_; open my $gp, '>', remove_later('measure.gp') or die $!; print {$gp} join "\n", 'set term png;', 'set output "measure.png";', 'set key left;', 'set logscale x;'; my $column = 2; my $command = qq(plot "$plot_file"); print {$gp} join ', ', map { my $s = qq($command using 1:$column with lines title "$_") +; $command= '""'; ++$column; $s } @langs; print {$gp} "\n"; close $gp; system 'cat measure.gp; echo; cat measure.dat'; 0 == system 'gnuplot', 'measure.gp' or die $!; } sub main { my %run = ( perl => sub { $^X, '-e', "for \$i (0..$_[0]) { \$s += \$i }" + }, ruby => sub { ruby => '-e', "s=0;0.upto($_[0]){|i|s+=i}" }, java => sub { java => 'Measure' }, c => sub { './a.out' }, erlang => sub { qw( erl -noshell -s measure main -s init stop +) }, pascal => sub { './measure' }, php => sub { php => '-r', '$s=0;for($i=0;$i<='.$_[0].'; $i++){$s+=$i;}' } ); my %time; for my $n (10, 100, 1e3, 1e4, 1e5, 1e6, 2.5e6, 5e6, 7.5e6, 1e7, 2.5e7, 5e7, 7.5e7, 1e8 ) { print STDERR "$n\n"; for my $lang (sort keys %run) { $time{$n}{$lang} = measure($run{$lang}, $n, prepare($lang, + $n)); } } create_file(my $plot_file = 'measure.dat', join "\n", map { my $t = $_; join ' ', $t, map $time{$t}{$_}, sort keys %{ $tim +e{$t} } } sort { $a <=> $b } keys %time); plot($plot_file, sort keys %run); remove_all(); } main();
To do something in the loop, the code calculates the sum of all the numbers it loops over (the sum isn't used anywhere, so clever optimizers might still optimize it away).
You might need to remove some of the languages from the %run hash if you don't have them installed, you can also add some if you like. Compiled languages need an entry in the %prepare hash, too.
It includes the startup time and the compilation time, but you can easily exclude the latter as written in the comment.
Output on my machine: Image
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: perl process slower and slower when loop number increase
by Anonymous Monk on Jan 22, 2018 at 17:06 UTC |