我正在讀取專有的二進制數據文件格式。所述格式基本上報頭,數據,size_of_previous_data,報頭,數據,size_of_previous_data,報頭,數據,size_of_previous_data,...頭的 部分包括數據的下一個塊的字節數以及後被立即列出其大小數據。標題爲256字節,數據通常爲〜2MB,size_of_previous_data爲32位int。讀取大文件的小分離塊(C++)
的文件一般都很大〜GB,我經常有幾十,通過他們對我想要的數據進行搜索。爲了做到這一點,我在代碼中做的第一件事是每個文件都是idex,即只讀入頭文件並記錄相關數據的位置(文件和字節數)。我的代碼基本上使用fstream :: read()準備好頭文件,檢查數據大小,使用fstream :: seekg()跳過數據,然後讀入size_of_previous_data,然後重複,直到到達文件末尾。
我的問題是,這個索引是痛苦的緩慢。數據在我的Windows 10筆記本電腦上的內部7200 rpm硬盤驅動器上,任務管理器顯示我的硬盤驅動器使用率已達到最大,但我的讀取速度僅爲1.5 MB/s,響應時間通常> 70 ms。我正在使用fstream :: get()讀取文件,使用std :: fstream讀取頭文件並將fstream :: seekg()移至下一個頭文件。
我已經異型我的代碼,並幾乎全部時間都花在了的fstream ::閱讀()的代碼讀取size_of_previous_data值。我認爲當我這樣做時,數據立即被緩衝,所以我的fstream :: read()獲得下一個頭幾乎沒有時間。
所以我想知道如果有一種方法來優化呢?幾乎在任何緩衝讀取中,我的整個緩衝區都可能被浪費(如果它是8kB緩衝區,則其中的97%會被浪費)。有沒有辦法縮小這個值,是否值得這麼做(也許底層操作系統緩衝區也是我無法改變的)?
爲什麼不讀一開始的所有文件? RAM的GB通常很好,但搜索GB大小的文件很慢並不令人驚訝 – user463035818
如果數據的大小已經存儲在頭中,那麼爲什麼不在搜索數據時跳過'size_of_previous_data' ?您可以保存讀數,直到您需要讀取數據本身,然後將其用作一種校驗和。如果您一次只讀取256個字節,則不需要比此更大的緩衝區。 –
如果您的操作系統支持它,請嘗試使用內存映射文件。操作系統將爲您處理將塊讀入內存。 –