2017-08-29 64 views
0

我正在編寫一些代碼,循環遍歷項目中的所有.rb文件,看看它們是否引用DateTime類。我第一次嘗試是這樣的:爲什麼調用系統grep比在Ruby中匹配要慢?

file_names.each do |file_name| 
    File.foreach(file_name) do |line| 
    return file_name if line.match(/DateTime/) 
    end 
end 

的算法表明,大約需要0.6秒運行到1100個文件,每個25次基準測試結果。不錯,但我認爲調用系統的grep命令可能會更快。我的第二次嘗試是這樣的:

file_names.each do |file_name| 
    return file_name if system("grep DateTime #{file_name} > /dev/null") 
end 

這需要35.6秒跑!有沒有人有任何洞察,爲什麼第二次嘗試表現如此糟糕?調用系統是緩慢的部分還是grep比內部ruby代碼慢?

+1

您的「第一次嘗試」似乎不包含'file_names.each'循環。此外,你從哪裏返回,一個方法?你怎麼稱呼它?這兩種嘗試都會產生相同的結果嗎? – Stefan

+1

在處理多個文件時'grep'可能會更快,但是當在循環中使用時,'system'的開銷很大。 – tadman

+0

嘗試使用反引號從所有文件中捕獲grep輸出(例如,將它們放在一個命令中,而不是在一個紅寶石循環中) –

回答

6

對系統調用slow partor是grep比內部ruby代碼慢嗎?

在你的情況下,調用系統比較慢。特別是因爲你如何爲每個文件創建一個新的OS進程

這意味着Ruby不得不要求操作系統創建1100個新的子進程(一次一個),並監視這些子進程的終止。因爲ruby中的所有文件IO都是以C語言編寫的(至少在mruby中),所以ruby腳本(它已經運行它自己的OS進程並分配了系統內存)會更快一些,打開文件並自行搜索,而不是創建1100個子進程。

+0

謝謝你的解釋。 – CodeSmith