2012-08-04 60 views
4

我有文件的真正的大集合,我的任務是打開一對夫婦從這個集合隨機文件對待自己的內容作爲一個整數集,使它的一個交集。檔案開放/閱讀語言的速度是否依賴?

這個過程是相當緩慢由於從磁盤讀取文件到內存中,所以我不知道是否從文件中讀取這個過程可以通過一些「快速」語言改寫我的程序來加快長的時間。目前我正在使用python,這對於這類工作可能是低效的。 (我可以實現自己的測試,如果我知道Python及JavaScript之外的其他語言...)

也將會把所有的日期到數據庫的幫助?無論如何,文件不會適合RAM,所以它只會在數據庫相關的開銷下再次從磁盤讀取數據。

文件的內容是長整數的列表。 90%的文件很小,不到10-20MB,但剩下的10%大約是100-200MB。作爲輸入有文件名,我需要讀取每個文件中給出的每個文件和輸出整數。 我試圖把這個數據在MongoDB中但那是基於方法純文本文件慢,因爲我試圖用蒙戈指數的能力和蒙戈不存儲索引在RAM中。 現在,我只是將最大的文件的10%和休息存儲在redis中,有時會訪問這些大文件。這顯然是暫時的解決方案,因爲我的數據增長了,而可用的RAM數量卻沒有。

+4

是不是在執行_anything_語言相關的速度? – 2012-08-04 01:55:13

+1

您是否需要訪問這些文件中的所有數據,或者只需選擇文件中的數據?如果是後者,使用''mmap''可能會更快。另外''numpy''可能會使內存中的數字存儲(並計算它們的交點)效率更高。對於磁盤存儲,可能考慮使用''hdf5''?你能更詳細地描述你已經嘗試過什麼,並提供這些文件性質的更多細節? – imm 2012-08-04 01:58:04

+0

@MattBall儘管所有的「現代」語言都有先進的編譯器/譯者,它們可以有效地處理簡單的案例,所以如果有改寫的話,重寫將是無法接受的。 – Moonwalker 2012-08-04 01:58:28

回答

3

你可以嘗試的一件事就是逐塊地計算文件的交集(即從每個塊中讀取x字節到存儲器中,計算它們的交點並繼續,最後計算所有交點的交集) 。

或者,你可以考慮使用一些「重型」庫來幫助你。考慮查看PyTables(使用HDF存儲)/使用numpy計算交叉點。這樣做的好處是HDF層應該能夠幫助處理不將整個數組結構同時保存在內存中 - 雖然我之前沒有嘗試過任何這些工具,但似乎他們提供了您所需要的。

+1

你可以勾畫出這種逐塊工作的代碼嗎?我不會立即看到它如何處理出現在兩個文件的不同塊中的相同整數。另外,你的意思是「所有交叉口的聯合」而不是「所有交叉口的交叉口」? – 2012-08-04 10:00:17

1

如果沒有文件包含重複的數字,我想試試這個:

sort file1 file2 | uniq -d 

如果它們可能包含重複,那麼你需要先消除重複:

sort -u file1 > /tmp/file1 
sort -u file2 > /tmp/file2 
cat /tmp/file1 /tmp/file2 | sort | uniq -d 

或者,如果你喜歡版本不(明確)使用臨時文件。

(sort -u file1; sort -u file2) | sort | uniq -d 

你不說什麼格式的文件(上面假設文本,每行一個整數)。如果它們採用某種二進制格式,那麼在應用上述命令之前,您還需要命令來轉換它們。通過使用管道您可以撰寫這一步驟是這樣的:

(decode file1 | sort -u ; decode file2 | sort -u) | sort | uniq -d 

這裏decode是一個程序,你會寫,它分析你的文件格式的名稱。

除了令人難以置信的簡短之外,這個shell解決方案的好處在於它可以處理任何大小的文件,即使它們不適合RAM。

從你的問題中不清楚你是否有2個或任意數量的文件相交(你的問題的開始是「一對夫婦」,最後是「文件名列表」)。例如,要處理5個文件而不是2個,請使用uniq -c | awk '{ if ($1=="5") print $2; }'而不是uniq -d

+0

作爲參考,「sort」如何處理大文件。 http://vkundeti.blogspot.ch/2008/03/tech-algorithmic-details-of-unix-sort.html – 2012-08-04 09:09:50