2013-08-01 30 views
1

[草莓的Perl v5.16.3,視窗7 64,通過執行CMD,例如C:\草莓> perl的test.pl 100000]

症狀:以下代碼:foreach (1..$ARGV[0]) { foo($_); },執行速度大概比我在這之前包含這個額外的行慢了20%:my $num = $ARGV[0];

問題:任何人都可以幫我理解爲什麼?

注意,在第二種情況下,我初始化並設置了$num後,我沒有在循環參數中使用$num。如果是這種情況,我可能會確信,在forloop中反覆測試$ARGV[0]比我自己定義的變量慢得多......但事實並非如此。

要跟蹤時間,我使用:use Time::HiRes; my $time = [Time::HiRes::gettimeofday()];在我的腳本的頂部,和:print "\n1: ", Time::HiRes::tv_interval($time);在底部。

困惑!

感謝,

邁克爾

編輯

我在內的整個腳本,與違規行前面的註釋......有趣的是,它看起來像的時間相差至少部分取決於我的冗餘初始化%h,以及@chain ......這很奇怪。

use Time::HiRes; my $time = [Time::HiRes::gettimeofday()]; 

    #my $max=$ARGV[0]; 
    my %h = (1=>1,89=>89); 
    $h{1}=1; 
    $h{89}=89; 
    my @chain=(); 
    my $ans=0; 

    sub sum{my $o=0; foreach (@_){$o+=$_}; return $o;} 

    foreach (1..$ARGV[0]-1){ 
     my $x=$_; 
     my @chain =(); 
     while(!exists($h{$x})){ 
      push(@chain,$x); 
      $x = sum(map {$_**2} split('',$x)); 
     } 
     foreach (@chain){$h{$_}=$h{$x} if !exists($h{$_});} 
    } 

    print "\n1: ", Time::HiRes::tv_interval($time); 
    foreach (1..$ARGV[0]){$ans++ if ($h{$_}==89);} 
    print "\n2: ", Time::HiRes::tv_interval($time); 
+1

不能確定地複製。你能發佈完整的基準代碼和狀態Perl版本/操作系統嗎? – amon

+0

感謝您的反饋。發佈編輯以包含一些信息。仍然試圖包括重要的代碼,但不讓我的帖子很可怕... –

+0

您的代碼似乎在1E-5秒(10微秒)的範圍內產生時間。這遠遠小到可以提供可用的結果。此外,你的代碼並不清楚你的時間。當以足夠的迭代運行[benchmark](https://metacpan.org/module/Benchmark)時,沒有真正的差異可見。 – amon

回答

2

在我的系統上(perl 5.16.3在GNU/Linux上)沒有可衡量的差異。計時的標準偏差大於不同版本的測量之間的差異。

對於腳本的每個變體,執行了10次執行。在所有情況下(0120000),$ARGV[0]3.5E5

沒有my $num = $ARGV[0]

$ perl measure.pl 
2.369921 2.38991 2.380969 4.419895 2.398861 2.420928 2.388721 2.368144 2.387212 2.386347 
mean: 2.5910908 
sigma: 0.609763793801797 

隨着my $num = $ARGV[0]

$ perl measure.pl 
4.435764 2.419485 2.403696 2.401771 2.411345 2.466776 4.408127 2.416889 2.389191 2.397409 
mean: 2.8150453 
sigma: 0.803721101668365 

measure.pl腳本:

use strict; use warnings; use 5.016; 
use List::Util 'sum'; 

my @times = map qx/perl your-algorithm.pl 3.5E5/, 1..10; 
chomp @times; 

say "@times"; 
say "mean: ", mean(@times); 
say "sigma: ", sigma(@times); 


sub mean { sum(@_)/@_ } 

sub sigma { 
    my $mean = mean(@_); 
    my $variance = sum(map { ($_-$mean)**2 } @_)/@_; 
    sqrt $variance; 
} 

隨着your-algorithm.pl減小,以便只有一個定時被印刷:

foreach (1..$ARGV[0]){$ans++ if ($h{$_}==89);} 
print Time::HiRes::tv_interval($time), "\n"; 
+0

當我刪除第二個foreach和第二個打印時,我也發現速度沒有明顯的差異。但是這沒有用,因爲我的腳本包含了第二個foreach和第二個print,這會產生速度上的差異。 –

+0

好的,我更新了,以便我的計時也包括該循環。這兩個版本的1-sigma範圍仍然重疊。因此我們不能推斷出版本的運行時間不同。 – amon

+0

我想我們的系統以不同的方式解釋腳本。始終如一,我仍然處於不同的時代。謝謝。 –