我在寫外部合併排序。它的工作方式如下:從大文件中讀取k個塊,在內存中對其進行排序,執行k路合併,完成。所以我需要在k路合併階段從文件的不同部分順序讀取。要做到這一點的最佳方式是:幾個ifstream或一個ifstream並尋求?另外,是否有一個易於異步IO的庫?幾個ifstream與ifstream +不斷尋求
回答
在同一個文件上一次使用一個ifstream
。不止一個浪費資源,並且您必須反正尋找(因爲默認ifstream
的文件指針從文件開頭開始)。
至於C++異步IO庫,請查看this question。
編輯:我最初誤解你正在嘗試做什麼(這Wikipedia article填補了我)。我不知道默認情況下有多少ifstream
緩衝區,但可以使用pubsetbuf(0, 0);
方法described here關閉緩衝區,然後執行自己的緩衝。然而,這可能比使用自動緩衝的多個ifstream
慢。有些基準測試是按順序進行的。
你不會「不得不去尋找」,因爲在多個數據流中,你需要爲每個文件塊(k)尋找一個數據流。使用單個流進行多路合併,每合併一個合併(n)大約一次,儘管如果長時間運行的項目來自單個塊,您可能會感到幸運。但是,如果數據最初是隨機排列的,那麼這種可能性可以忽略不計。 – 2010-04-20 13:26:29
肯定嘗試多個流。尋找可能會拋出內部緩衝數據(至少在該過程中,即使操作系統將其保留在緩存中),並且如果您正在排序的項目很小,確實可能會非常昂貴。
無論如何,比較兩種fstream策略的性能應該不會太難。做一個k = 2的簡單實驗。
請注意,一個進程可以同時打開的文件數量可能有限制(ulimit -n
)。如果達到此目的,則可能需要考慮使用單個數據流,但是要手動緩存來自每個k個數據塊的數據。
如果文件足夠小(相當於:地址空間足夠大),則可能需要使用多個指針來映射文件並使用多個指針。
打開的文件或打開的文件流的數量是否有限制(我只需要訪問1個文件,但是有很多文件流)? 不幸的是文件大小遠遠大於內存大小。外部排序就是這種情況。 – SpyBot 2010-04-20 14:19:10
可能是溪流,但我並不完全確定。當* NIX說「打開文件」時,我認爲這意味着文件描述符的數量,而不是它們指向的不同文件的數量。我提到了mmap,因爲它不需要文件適合內存,只需要給它一個地址範圍(在32或64位虛擬地址空間內)。然後,操作系統執行文件的分段部分進出物理RAM,因爲它們被使用。 – 2010-04-20 15:28:47
- 1. 問題與ifstream的
- 2. 閱讀「*」與ifstream的
- 3. Ifstream trouble
- 4. ifstream :: read不工作?
- 5. 不能由ifstream的
- 6. Ifstream不起作用
- 7. 我不明白ifstream
- 8. 用ifstream在大文件中尋找
- 9. 從ifstream的*轉換爲ifstream的&
- 10. ifstream var.fail()函數
- 11. C++從ifstream的
- 12. Cin.get()打開與ifstream的
- 13. getline()與ifstream指針錯誤?
- 14. ifstream ofstream on mac
- 15. 類內的Ifstream
- 16. ifstream getline問題
- 17. ifstream - > ofstream C++
- 18. C++ ifstream to char *
- 19. C++ ifstream object「reseting」
- 20. C++ - 從ifstream的
- 21. 從ifstream的
- 22. ifstream_iterator和ifstream
- 23. 不能包含ifstream「致命錯誤:'ifstream'文件未找到」
- 24. C++ ifstream I/O?
- 25. 閱讀整個std :: ifstream堆
- 26. 處理不好的ifstream
- 27. 文件不會打開ifstream
- 28. C++ ifstream getline不工作
- 29. ifstream不打開文件
- 30. ifstream的不讀就想值
我會爭論fstream _is_一個簡單的異步IO庫:-) – Cameron 2010-04-20 13:07:52
@Cameron除了不是異步 – 2010-04-20 13:18:15
@尼爾:對不起,我是設法混淆異步與隨機訪問。我需要更多的睡眠! – Cameron 2010-04-20 13:24:06