【问题标题】:Performance impact of realloc ()realloc() 的性能影响
【发布时间】:2011-07-17 22:15:41
【问题描述】:

我有一个记录列表,一开始我不知道记录的数量。我需要将它们读入数组。 因此,是否建议逐个读取所有记录并逐个执行 realloc 并在元素出现时继续增加数组大小,或者我应该花一遍来确定记录的数量并且只执行一次 malloc 吗?哪个计算成本更低?

【问题讨论】:

  • 有一个中间立场。您可以分配一个大块(我不知道,100 个?),如果填满,重新分配到该大小的 2 倍(或 1.5 倍或任何有意义的)。这是动态列表的常用策略。
  • 同时实施和衡量...这是在时间关键部分吗?还是只是出于好奇?

标签: c algorithm programming-languages


【解决方案1】:

realloc 并不是很贵。但是为每个元素调用realloc 有点多。我建议你这样做:

  • 从尺寸开始
  • 添加元素时,检查是否有足够的空间
  • 当您没有足够的空间时,将当前数量翻倍

正确猜测适当的初始大小也有帮助。因此,如果 60% 的输入少于 100 条记录,请从那开始。

【讨论】:

  • realloc 调用可能会也可能不会很昂贵,因为如果必须移动内容需要线性时间。我不得不重写一个程序来预先计算输出大小,因为重新分配时间非常重要,即使将数组大小加倍也是如此。
  • 加倍并不是获得线性性能的必要条件,但您应该始终使用 constant 因子,按当前大小 * K 增加某个值 K,该值由平衡成本的实验确定以浪费空间为代价的重新分配。例如,C++STL 使用 1.5。完成添加到数组后,还可以向下重新分配以恢复未使用的内存。
  • 没有完美的方法。我自己过去曾使用过一个常数因子(将尺寸翻倍对于大尺寸来说是有问题的)。所以我同意,其他方法可能效果更好,具体取决于应用程序。
  • 使用realloc() 的重要一点是不要以恒定数量增长块,而是以相对数量增长它,就像@TokenMacGuy说过。这样,开销在缓冲区大小中保持线性。更直接地说,每当您添加到容器中时,realloc()'ing 都会导致性能灾难。
  • re cnicutar:在内存不足时推测性地预分配空间总是注定要失败的。另一种选择可能是构建一个链表,然后以系统的方式将单个项目收集到更大的数组块中,实际上是用带宽换取空间,基于此更受限制。
【解决方案2】:

正如其他人所指出的,当数组变满时将其大小加倍是一种常见的技术。事实上,使用这种技术可以确保每个元素所花费的时间不超过恒定量,正如 on WikiPedia 所解释的那样。

根据代码需要的速度以及您正在读取的来源,在单独的通道中计算输出的大小可能是个好主意。如果您正在从磁盘读取,您可能应该使用动态数组,否则您可能应该做任何更容易实现的事情。

【讨论】:

【解决方案3】:

你不应该realloc( )一个接一个。

此类事情的最佳策略取决于您正在执行的具体操作,但一种常见、简单且近乎最佳的方法是每当您的空间不足时将分配大小增加两倍你的数组。

【讨论】:

    【解决方案4】:

    如果可能的话,您也可以考虑为您的任务使用链表而不是数组。只需malloc 即可添加新元素。

    【讨论】:

      猜你喜欢
      • 2014-07-18
      • 1970-01-01
      • 1970-01-01
      • 2016-05-17
      • 2015-04-08
      • 1970-01-01
      • 2013-08-30
      • 2021-03-09
      • 2011-06-08
      相关资源
      最近更新 更多