2014-02-14 44 views
6

我想爲大量的文件構建一個解析器,而且我找不到關於我可能稱之爲「嵌套goroutines」的資源(也許這不是正確的名稱?)。我們應該嵌套goroutines嗎?

給定了很多文件,每個文件都有很多行。我應該怎麼做:

for file in folder: 
    go do1 

def do1: 
    for line in file: 
     go do2 

def do2: 
    do_something 

或者我應該用夠程的只有「一平」,並執行以下操作:

for file in folder: 
    for line in file: 
     go do_something 

我的問題主要目標的性能問題。

感謝您接觸到這句話!

+0

難道只是嘗試兩種看到?我認爲它可能強烈依賴於您的操作系統,磁盤和文件系統。並行性太少意味着阻塞等待I/O,太多意味着磁盤抖動。 – Thomas

+0

goroutines是獨立預定的。無論你是從嵌套循環還是嵌套函數調用它們都無關緊要。調用N goroutines調用N goroutines。 – JimB

+1

恕我直言,還有其他更好的工具適合這種工作,不要重新發明weel,看看hadoop或火花項目 – fabrizioM

回答

5

如果你經歷了你指定的架構,你很有可能會耗盡CPU/Mem/etc,因爲你將創建任意數量的工作者。我建議,而是採用可讓您通過頻道節流的架構。例如:

在您的主處理饋送文件到一個信道:

for _, file := range folder { 
    fileChan <- file 
} 

然後在另一個的goroutine文件分解成線和進料的那些成信道:

for { 
    select{ 
    case file := <-fileChan 
    for _, line := range file { 
     lineChan <- line 
    } 
    } 
} 

然後在一個第三個goroutine彈出行,做你會與他們:

for { 
    select{ 
    case line := <-lineChan: 
    // process the line 
    } 
} 

主要進步與此相對應的是,您可以創建儘可能多或更少的程序,因爲系統可以處理這些程序,並將它們傳遞到所有相同的頻道,並且首先通過頻道首先進行處理的任何人都可以處理它,這樣您就可以節制金額您正在使用的資源。

這裏是一個工作示例:http://play.golang.org/p/-Qjd0sTtyP

+5

這是一個非常尷尬和容易出錯的方式來編寫'line for line:= range lineChan {}' – Dustin

1

答案取決於處理器密集型的操作在每一行是如何。

如果行操作是短暫的,絕對不用爲每行產生一個goroutine。

如果價格昂貴(想想〜5秒或更長),請謹慎行事。你可能會用完內存。從Go 1.4開始,產生一個goroutine分配一個2048字節的堆棧。對於2百萬行,您可以單獨爲goroutine堆棧分配超過2GB的RAM。考慮是否值得分配這個內存。

總之,你可能會用下面的設置獲得最佳的效果:

for file in folder: 
    go process_file(file) 

如果文件數超過CPU的數量,你可能有足夠的併發掩蓋磁盤I/O延遲涉及從磁盤讀取文件。

相關問題