Perlで、shを実行できますよね。
shって結構お手軽で便利なコマンドがあるので、perlの中でも使いがちがんですが、実はかなり実行速度が遅いんですよね。
こういう話をどっかで聞いていたんで、実際にテストしてみました。
このテストでは、perlでファイルをreadするときに、perl内でハンドルをopenして読み込むか、sh呼び出してcatを用いるかで比較しました。
するとこんな結果になりました。
# ./roupe_test.pl === Start!! === --- PERL_TEST(FILE Read [perl_roupe]) --- [test 1](0s .85510ms) [test 2](0s .73861ms) [test 3](0s .73888ms) [test 4](0s .74111ms) [test 5](0s .74027ms) --- PERL_TEST(FILE Read [sh_roupe]) --- [test 1](4s .-69818ms) [test 2](4s .-182927ms) [test 3](4s .-141415ms) [test 4](4s .-171225ms) [test 5](3s .855982ms) === Finish!! ===
これって結構な差ですよね。
実際にperl上でshを呼び出すときのメモリの使い方とかは、厳密にチェックしてないので、完璧なテストではないですが、目安にはなると思います。
perlでsh呼び出す方が、約50倍くらい遅いです。
これって、この処理を多様してたら、単純計算でPerlで1分の処理が、sh使ってファイルreadすると50分かかるんですよね。
意外なほどの差が出ました。
コーディングでは気をつけた方がよさそうです。
ソースは以下
#!/usr/bin/perl use warnings; use strict; use Time::HiRes qw(gettimeofday); #################### ### MAIN ROUTINE ### #################### my $count_max = 1000; my ($i,$run_flug,$run_time); my %type = (1,"perl_roupe", 2,"sh_roupe"); print "=== Start!! ===\n"; for ($run_flug=1 ;$run_flug<=2 ;$run_flug++) { print "--- PERL_TEST(FILE Read [$type{$run_flug}]) ---\n"; for ($i=1 ;$i<=2 ;$i++) { print "[test $i]("; if($run_flug == 1) { $run_time = perl_roupe($count_max); } elsif($run_flug == 2) { $run_time = sh_roupe($count_max); } else { die "=== Error!!===\n"; } printf $run_time.")\n"; } print "\n"; } print "=== Finish!! ===\n"; ################### ### SUB ROUTINE ### ################### sub sh_roupe { local(*count_max); my $sh_value = ""; my $count = 0; my $run_time; my ($Ssec,$Smicrosec) = gettimeofday; while($count_max != $count) { $sh_value = `cat test.txt`; $count++; } my ($Fsec,$Fmicrosec) = gettimeofday; $run_time = $Fsec - $Ssec; $run_time .= "s ."; $run_time .= $Fmicrosec - $Smicrosec; $run_time .= "ms"; return $run_time; } sub perl_roupe { local(*count_max); my $perl_value = ""; my $count = 0; my $run_time; my ($Ssec,$Smicrosec) = gettimeofday; while($count_max != $count) { open(HANDLE, "< test.txt"); $perl_value =; close HANDLE; $count++; } my ($Fsec,$Fmicrosec) = gettimeofday; $run_time = $Fsec - $Ssec; $run_time .= "s ."; $run_time .= $Fmicrosec - $Smicrosec; $run_time .= "ms"; return $run_time; }