抱歉,如果之前有人问过这个问题,我无法找到我正在寻找的东西。
我正在从列表中读取字段并将它们写入内存块。我可以
- 遍历整个列表,找到所需的总大小,做一个
malloc
然后再次遍历列表并复制每个字段; - 在我写值时遍历整个列表和
realloc
内存块;
现在,第一个对我来说似乎是最有效的(最少的调用次数)。两种方法的优缺点是什么?
感谢您的时间。
抱歉,如果之前有人问过这个问题,我无法找到我正在寻找的东西。
我正在从列表中读取字段并将它们写入内存块。我可以
malloc
然后再次遍历列表并复制每个字段;realloc
内存块;现在,第一个对我来说似乎是最有效的(最少的调用次数)。两种方法的优缺点是什么?
感谢您的时间。
第一种方法几乎总是更好。realloc() 通常通过将内存块的全部内容复制到新分配的更大块中来工作。所以n reallocs 可能意味着 n 个副本,每一个都比上一个大。(如果您每次都在分配中添加 m 个字节,那么第一个 realloc 必须复制 m 个字节,下一个 2m,下一个 3m,...)。
迂腐的答案是 realloc() 的内部性能影响是特定于实现的,没有由标准明确定义,在某些实现中,它可以由立即移动字节的魔法仙女工作,等等等等——但在任何现实的实现中, realloc() 表示副本。
根据您认为最有可能的最大值,最初分配相当数量的空间可能会更好。
然后,如果你发现你需要更多的空间,不要只为额外的空间分配足够的空间,而是分配一大块额外的空间。
这将最大限度地减少重新分配的次数,同时仍然只处理一次列表。
例如,最初分配 100K。如果你发现你需要更多,重新分配到 200K,即使你只需要 101K。
不要重新发明轮子并使用darray
实现类似于 paxdiablo 描述的方法的 CCAN。在 GitHub 上查看darray