4

任务是将二进制文件解析到内存中。但是,我事先不知道需要分配的内存量。

哪种方法更可取:当我在解析例程中进行时执行多个小型 malloc,或者首先遍历文件以确定所需的内存量,然后再次解析?

任何提示表示赞赏。

4

5 回答 5

6

在几乎所有情况下,一个大分配都比许多小分配好。这可以防止碎片,减少系统调用。它通常通过更好的局部性带来更好的性能。

一种常见的技术是先分配一个小段,然后按固定因子(通常1.5)重新分配一个更大的段。收集所有元素后,如果认为过度分配很大,则可以将内存固定为最大大小。

无论如何:首先实现最简单的。如果您有性能问题:基准测试。然后优化。事实证明,分配甚至不是您的瓶颈。

编辑:正如 R.. 提到的,通过推理内存上限及其与文件长度的关系,您可能会很好地了解分配多少。大多数好的二进制格式还在标题段中包含长度和大小信息。如果您可以通过一些算术和/或文件搜索来计算出数据结构所需的确切大小,那么您就是赢家。

于 2012-07-25T00:11:13.227 回答
3

您是否看过可能mmap()为此使用 an ?有关更多信息,请参阅此链接。基本上,您只需将文件映射到内存中并像访问内存块一样访问它,malloc()完全避免 s 。

于 2012-07-25T00:13:35.760 回答
2

这是一个经典的时空权衡。假设您需要全部内容,分配大量小块的效率可能低于一个大块。

理想情况下,文件格式应该对元数据进行编码,例如块的大小、块的数量等。鉴于磁盘访问的延迟与内存的速度相比,读取文件以确定所需的大小可能需要更长的时间。

最有效的方法还取决于需要多少处理。你提到解析,但它是一个二进制文件。大概有很多块和可变大小的结构需要遍历?

您可以尝试以下几种策略:

  • 如果文件不是太大而无法放入内存,则可以查询文件系统以查看文件有多大,将其作为一大块读取,然后将其拉到内存中。这将非常快,但会占用大量内存。

  • 根据二进制文件的结构,您可能可以进行几次fseek()调用来确定您需要读取的块有多大(如果您不需要整个文件)并读取它们。

  • 您可以使用mmap()将文件映射到内存并让运行时管理将数据分页到内存中。

于 2012-07-25T00:18:50.240 回答
1

遍历文件以确定它的大小和所需的内存量绝对不是要走的路——磁盘 I/O 非常昂贵。

另一种选择是获取文件大小,然后分配内存。有关如何获取文件大小的详细信息,请参阅此 Q/A。但是,这种方法也不是很有效。

总而言之,它实际上取决于您如何读取数据以及如何解析它。例如,拥有一些相当大的数据块以及异步文件 I/O 可能最适合您。但这是实施起来相对复杂的任务。

最简单和最有效的开始可能是使用mmap文件的内容并将其“映射”到内存中。

于 2012-07-25T00:14:45.733 回答
1

至少部分没有通用答案,因为您没有定义“首选”。最简单的?最快的?需要最少的堆?另外,“解析二进制文件”是什么意思?解析通常是为了创建数据结构而对人类可读的文本进行的。

每个malloc通常都有一个小的开销。但是,除非最终的数据结构很大,否则不太可能产生任何显着差异。

使用干净的接口生成最清晰的代码,以便您以后可以替换分配方法。然后只有在你知道有问题之后才担心优化。

于 2012-07-25T00:16:57.337 回答