2011-05-22 42 views

回答

6

是的 - 或者至少我是這樣解釋這個結果的。

$ perl -e "map {0} <>" big_data_file 
Out of memory! 

$ perl -e "map {0} 1 .. 1000000000" 
Out of memory! 

有人可能會懷疑我們是否耗盡內存,因爲Perl是嘗試存儲的map輸出。然而,我的理解是,Perl被優化以避免在無效環境中調用map時的工作。有關具體示例,請參閱this question中的討論。

也許更好的例子:基於評論

$ perl -e "sub nothing {} map nothing(), <>" big_data_file 
Out of memory! 

,看來這個問題是由一個願望,一種簡潔的語法處理大量數據時的動機。

open(my $handle, '<', 'big_data_file') or die $!; 

# An ordinary while loop to process a data file. 
while (my $line = <$handle>){ 
    foo($line); 
} 

# Here Perl assigns each line to $_. 
while (<$handle>){ 
    foo($_); 
} 

# And here we do the same thing on one line. 
foo($_) while <$handle>; 
+0

一個簡單的測試用例。謝謝。 – 2011-05-22 15:34:31

+1

實際上,在這兩種情況下,你都要用'0'值加載一個列表。如果您使用for循環並將數字「推」到數組,則會得到相同的錯誤。雖然在這種情況下,它並不是即時的。 – TLP 2011-05-22 15:47:27

+0

雖然我沒有將返回的數據加載到數組中, 'map {print FILEHANDLE function($ _)} ;'。我只是喜歡在小操作上使用map而不是foreach。 – 2011-05-22 15:52:04

2

你問我假設的問題是:是否map功能啜食文件它開始處理之前,或是否通過線使用線。

讓我們做有關處理列表的快速比較:

while (<FILEHANDLE>) { ... } 

這個案例清楚地線採用線。每次迭代,獲取$_的新值。

for my $line (<FILEHANDLE>) { ... } 

在這種情況下,LIST是在循環開始之前擴大。在http://perldoc.perl.org/functions/map.html中有一個對map的引用,它類似於foreach循環,我確信LISTs在被傳遞給函數之前被展開。

+0

我不認爲它在這種情況下是沒有爭議的:'map {print FILEHANDLE function($ _)} ;'編輯:看起來它加載將文件存入內存(請參閱FMc的答案),因此我將使用foreach循環而不是地圖。 – 2011-05-22 15:34:00

+0

@Eric是的,你說得對..沒有明確的答案,因爲地圖可以做任何想做的事情。我會刪除那部分.. – TLP 2011-05-22 15:38:41

3

是的,操作數爲map,foreach循環和子呼叫在map之前被評估,foreach循環或子呼叫甚至開始。

一個例外:

for my $i (EXPR_X..EXPR_Y) 

(有或無my $i)被優化成一個計數循環,沿

my $x = EXPR_X; 
my $y = EXPR_Y; 
for (my $i = $x; $i <= $y; ++$i) 

Perl6線的東西都會有惰性列表的原生支持。

+0

你是什麼意思的「子呼叫?」 – 2011-05-23 04:09:52

+0

@Eric Pruitt,'f()',參數是操作數。 – ikegami 2011-05-23 18:36:35

相關問題