2011-09-26 86 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|=中看到的唯一优点是它可以利用某些特定于平台的技巧或大字节序列,但我认为编译器将能够优化您的大“或者“循环”。