任务是将二进制文件解析到内存中。但是,我不知道分配所需的内存量。
哪种方法更可取:在解析例程中进行多个小型malloc,或者首先遍历文件以确定所需的内存量,然后再次解析?
任何提示都表示赞赏。
答案 0 :(得分:6)
在几乎所有情况下,一个大的分配比许多小分配更好。这可以防止碎片,减少系统调用。它通常会通过更好的地点来提高性能。
一种常见的技术是先分配一个小段,然后按固定因子(通常为1.5
)重新分配一个小段。收集完所有元素后,如果认为过度分配很大,则可以将内存固定为最大大小。
无论如何:首先实施最简单的一个。如果您遇到性能问题:基准测试。然后优化。可能会发现分配甚至不是你的瓶颈。
编辑:由于R ..提到您可以通过推理上限内存及其与文件长度的关系来了解分配多少。大多数好的二进制格式还包含标题段中的长度和大小信息。如果您可以通过一些算术和/或文件搜索来确定数据结构所需的确切大小,那么您就是胜利的一方。
答案 1 :(得分:3)
您是否考虑过使用mmap()
?有关详细信息,请参阅this link。基本上,您只需将文件映射到内存中,并将其作为内存块进行访问,完全避免使用malloc()
。
答案 2 :(得分:2)
这是一个经典的时空权衡。假设您需要整个内容,分配大量小块的效率可能低于一个大块。
理想情况下,文件格式应编码元数据,例如块的大小,块的数量等。鉴于磁盘访问的延迟与内存速度相比,读取文件以确定所需的大小可能需要更长的时间。
最有效的方法还取决于需要多少处理。你提到解析,但它是一个二进制文件。据推测,你需要遍历许多块和可变大小的结构?
您可以尝试一些策略:
如果文件不是太大而无法容纳在内存中,您可以查询文件系统以查看文件的大小,将其作为一个大块读取,然后将其拉到内存中。这将非常快,但使用大量内存。
根据二进制文件的结构,您可能可以进行一些fseek()
调用,以确定需要读取的块大小(如果您不需要整个文件),然后阅读那些。
您可以使用mmap()
将文件映射到内存中,让运行时管理将数据分页到内存中。
答案 3 :(得分:1)
遍历文件以确定其所需的内存大小和内存量绝对不是最佳选择 - 磁盘I / O非常昂贵。
另一种选择是获取文件大小然后分配内存。有关如何获取文件大小的详细信息,请参阅this Q/A。但是,这种方法效率也不高。
总而言之,它实际上取决于您如何读取数据以及如何解析数据。例如,拥有一些相当大的数据块以及异步文件I / O可能最适合您。但这是一项相对复杂的任务。
开始时最容易和最有效的事情可能是使用mmap
并将文件内容“映射”到内存中。
答案 4 :(得分:1)
至少部分没有一般性答案,因为你没有定义“更好”。简单?最快的?需要最少的堆?另外,“解析二进制文件”是什么意思?解析通常是用于人类可读文本的,以便创建数据结构。
每个malloc
通常都有很小的开销。但是,除非最终的数据结构很大,否则不太可能产生任何显着差异。
使用干净的接口做什么产生最清晰的代码,以便您以后可以替换分配方法。只有在您知道存在问题后才会担心优化。