2014-04-16 83 views
4

這是我的Perl代碼爲什麼一個小循環中的大循環比大循環中的小循環更快?

$big=10_000_000; 
#A:big loop outside 
my $begin_time = time; 
foreach my $i (1..$big) { 
     foreach my $p (1..10){ 
     } 
} 
my $end_time = time; 
my $t1=$end_time-$begin_time; 

#B:small loop outside 
my $begin_time = time; 
foreach my $i (1..10){ 
    foreach my $p (1..$big){ 
    } 
} 
my $end_time = time; 
my $t2=$end_time-$begin_time; 

#output 
print $t1; 
print "\n"; 
print $t2; 

T1 =8秒
T2 =3秒

利用Mathematica代碼:

Timing[Do[2, {i, 1, 10}, {j, 2*1, 10^7}]] 
output:{14.328, Null} 
Timing[Do[2, {j, 1, 2*10^7}, {i, 1, 10}]] 
output:{30.937, Null} 

爲什麼大環外需要更多時間?

+0

'perl -MO =簡明script.pl'在第一種情況下給出了更多的操作碼。 –

+0

我的母語不是英語,但你理解我的意思非常好!感謝您的編輯 – cn8341

+1

應該指出,如果你在循環中做了一些真正的計算,性能可能會非常好地反轉 - 不要得出一個清晰的結論由此。 – agentp

回答

9

在執行內部循環時有一定的開銷(初始化變量;使檢查看它是否應該結束),在第一種情況下,您將損失10,000,000次開銷;在第二,你只做了10次。

編輯: 讓s是設置循環(例如,初始化變量)和迭代循環的時間(例如,測試結束條件)的時間。然後:

大內環

T = s1 + 10 * (i1 + s2 + 10,000,000*i2) 
    = s1 + 10*i1 + 10*s2 + 100,000,000*i2 

大外環

T = s1 + 10,000,000 * (i1 + s2 + 10*i2) 
    = s1 + 10,000,000*i1 + 10,000,000*s2 + 100,000,000*i2 

差異

diff = 9,999,990*i1 + 9,999,990*s2 

所以外循環(i1)的迭代時間和內循環(s2)的建立時間都是大外循環比內循環大9,999,990倍。

+0

它是10,000,000次,而不是10,000。在兩種情況下,檢查循環是否應該結束的時間是相同的:這只是初始循環設置和後來拆除不同, – Borodin

+0

@Borodin - 抱歉,誤讀了數字。增加了關於設置和迭代循環的更多細節。 – TripeHound

+1

@Borodin:在兩種情況下,內循環的確被檢查了相同的次數。外環在一種情況下檢查10次,在另一種情況下檢查10E6次。 – Arkadiy