2011-09-26 85 views
1

我有兩個二進制文件(數十MB的順序),並且我希望或每一位這些文件。當然,我希望它儘可能高效。對C/C++中的大文件二進制數據進行的邏輯運算

所以我有兩種想法做到這一點,但我仍然認爲(我有點覺得)應該是一種我不知道的更有效的方法。

給定的文件a和b ..什麼我想要做的就是A = A | B

  1. 加載兩個文件,分析它們在兩個巨大的std ::位集和或在一起
  2. 裝兩個文件逐字節和或他們,如果一個巨大的循環...

有沒有其他的方式來做到這一點?

回答

6

不要逐字節地進行。那會很慢。相反,請以塊爲單位讀取文件。查找您的系統的塊大小(4k?8K?64k?),並使用該大小的塊讀取文件。然後你可以遍歷內存中的字節流並在那裏進行OR操作。從邏輯上講,即使你一次只能讀一個字節,操作系統仍然會讀取整個數據塊,然後丟掉除了你想要的字節以外的所有數據。下一次該塊將被緩存,但它仍然會通過您想要的每個字節的完整讀取動作。所以......只需將整個塊吸入內存中,並節省自己的開銷。

+1

+1我同意。如果您不介意將整個文件保存在RAM中,則可以流式處理/加載整個文件,然後遍歷字節或單詞並在那裏執行按位操作。另外,順序磁盤訪問比隨機訪問要快得多,因此一次抓取儘可能多。 – user

+0

因爲我沒有真正的內存限制,所以我可以一次讀取所有內存,然後使用for循環逐字節讀取它們!這是你最好的建議嗎? – Amir

+0

以塊爲單位的塊讀取總是比逐字節讀取效率更高。但不管磁盤系統的細節如何,絕對沒有理由一次只對8位進行「或」操作。 32位機器可以以與單字節相同的週期數同時執行32位操作。 –

3

我會建議一次加載一個塊的兩個文件,其中塊是數據的適當部分。最好的大小取決於你的操作系統和文件系統,但它通常是類似於簇大小,或者2 *簇大小,等等......你將不得不運行一些測試來確定最佳緩衝區大小。

0

我不認爲你會有任何性能優勢(如果在你的「第二選項」中,你將以大塊加載文件),畢竟你會使用一個大的堆棧分配緩衝區在這兩種情況下(這是std::bitset歸結爲什麼),所以請選擇你最喜歡的那個。

除了清晰之外,我在std::bitset::operator|=中看到的唯一優點是它可以利用某些特定於平臺的技巧或大字節序列,但我認爲編譯器將能夠優化您的大「或者「循環」。