“编程珍珠”:搜索

Posted

技术标签:

【中文标题】“编程珍珠”:搜索【英文标题】:“Programming Pearls”: Searching 【发布时间】:2012-08-13 13:11:15 【问题描述】:

我们可以通过保存一个集合来避免对存储分配器的多次调用 他自己的结构中的可用节点。

这个思想可以应用到二叉搜索树数据结构中。

作者说:“一次性分配节点可以大大减少 树的空间需求,将运行时间减少了大约三分之一。"

我很好奇这个技巧如何减少空间需求。我的意思是如果我们 想要构建一个有四个节点的二叉搜索树,我们需要分配 这四个节点的内存,无论我们是一一分配还是全部分配 一次。

【问题讨论】:

【参考方案1】:

这与 Java 如何处理字符串有关。而当你连接到一个字符串时,你实际上是在使用 3 个字符串对象:旧字符串、新段和新结果。最终垃圾收集器清理干净,但在这种情况下(我的字符串示例和您的程序二进制搜索) - 您正在以一种浪费的方式增加内存空间。至少我是这么理解的。

【讨论】:

【参考方案2】:

众所周知,内存分配器不擅长分配非常小的对象。过去十年情况有所改善,但书中的诀窍仍然适用。

大多数分配器在分配给您的块中保留附加信息,以便它们可以正确释放内存。例如,malloc/free 对 C 或 new[]/delete[] 对 C++ 需要将实际内存块的长度信息保存在某处;通常,这些数据在返回给您的地址之前的四个字节中结束。

这意味着每次分配至少会浪费四个额外的字节。如果您的树节点占用 12 个字节(两个指针各占 4 个字节,数字占 4 个字节),则将为每个节点分配 16 个字节 - 增加 33.3%。

内存分配器还需要执行额外的簿记。每次从堆中取出一个块时,分配器都必须考虑它。

最后,你的树使用的内存越多,当当前节点被处理时,相邻节点在缓存中被获取的机会就越小,因为内存中到下一个节点的距离。

【讨论】:

以上是关于“编程珍珠”:搜索的主要内容,如果未能解决你的问题,请参考以下文章

为啥此示例在字符串比较中使用空填充? “编程珍珠”:一串串珍珠

编程珍珠中的词频

“编程珍珠”:qsort 的冲突类型

来自编程珍珠的示例

使用更多空间编程珍珠的恒定时间初始化 - 第 1 列

旋转序列的两种算法的速度。 (摘自《编程珍珠》一书)