【问题标题】:Best way to implement a dynamic stack type? or Am i abusing realloc?实现动态堆栈类型的最佳方法?还是我在滥用 realloc?
【发布时间】:2010-11-17 09:35:36
【问题描述】:

我正在使用一种没有本机堆栈类型的晦涩语言,所以我实现了自己的。现在,在网上阅读我发现了一些不同的方法来做到这一点。

这是我的实现(伪代码)

//push method
function Push(int)
{
    Increase (realloc) stack by 4 bytes;
    Push int into the new memory area;
}

//pop method
function Pop()
{
    collect int from the top of the stack;
    reallocate (realloc) the stack to shrink it by 4 bytes;
    return int;
}

现在有人说在弹出一个值后使用 realloc() 调用来调整堆栈的大小不利于性能,所以我有几个问题:

  1. 最好只使用 malloc 增加堆栈然后在程序结束时释放它吗?
  2. 要调整堆栈大小(推送),最好增加 4 个字节或更多?
  3. 最佳做法是通过将分配的内存加倍来增加堆栈吗?
  4. 您对上述代码有何看法?

【问题讨论】:

    标签: performance memory-management stack realloc


    【解决方案1】:

    标准技术是仅将大小增加 2 倍,仅在有效内存使用量小于四分之一时缩小。

    这样你可以确保你使用的内存永远不会超过 O(你需要的内存),并且你还可以证明堆栈是摊销的常数时间。

    (这样看:您为每个进入或退出堆栈的项目支付 3 美分。其中两个将在下一次复制时使用。)

    Link to wikipedia article explaining in more details

    【讨论】:

      【解决方案2】:

      绝对不要一次增长和缩小 4 个字节。你的堆会变得非常碎片化,你会在分配器上花费太多时间。即使在内存有限的架构上,您也不希望像那样对内存进行微观管理。

      选择“页面大小”,并按该数量递增。通常建议将尺寸加倍,但我不确定为什么会这样。您可能更了解如何使用堆栈来了解如何最好地增加大小。

      【讨论】:

      • 大小加倍避免为小型结构分配完整的“页面”。通常你翻倍直到到达一个页面,然后增加页面大小的数量
      【解决方案3】:

      在流行的库中实现的几乎每个可变大小结构都做了一些小的优化以避免一直重新分配。请记住,它通常必须复制数据以使其更大。

      通常它会以更大的数量增长。一个常见的策略是将大小加倍,直到达到某个限制,然后在那里增长一个固定的数量。而对于缩小,不要担心调整大小,直到它浪费了一半以上的大小。

      OTOH,一些 realloc() 实现已经在幕后为您做到了。唉,我怀疑你的“晦涩的语言”能做到……

      【讨论】:

      • 同意,除了下降位的一半大小。我可以在“半使用”限制附近生成一系列插入/删除,这将使您重新分配每个操作。
      • 是的,可以进行很多调整;但是在缩小尺寸时,将尺寸调整为紧身尺寸并不明智,最好是原始尺寸的 3/4(保留 2/3 使用)
      猜你喜欢
      • 2011-01-04
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      • 1970-01-01
      • 2015-09-07
      • 2015-11-15
      • 1970-01-01
      • 2010-11-15
      相关资源
      最近更新 更多