在这种情况下,如何决定堆栈、堆和boost::池的分配

How to decide on stack vs heap vs boost::pool allocation in a case like this?

本文关键字:boost 堆和 分配 堆栈 这种情况下 何决定 决定      更新时间:2023-10-16

我有一个类,它使用boost::variant来存储双精度或字符串,如下所示:

class value
{
  boost::variant<double, std::string> val;
};

对于我正在玩的玩具解释器来说,它应该是一个不可变的值类型。起初,通过const引用传递它并按值返回它似乎是个好主意,并始终在堆栈上分配它,因为我希望它被视为基元。然而,后来我看到它的大小是40字节(主要是由于std::string的大小),我有点担心。我知道我不应该在堆栈上分配大块内存,但多大才算太大呢?

此外,每次返回时复制40个字节,尤其是因为值是不可变的,甚至不需要复制,这似乎有点浪费。

常规堆分配选项似乎不太吸引人,因为我每秒可以有数千个这样的分配/释放。

我提出的最后一个选项是使用boost::pool在需要时分配这些对象,并使用boost::shared_ptr来管理它们的生存期。然而,由于解释器负责内存分配(内存分配的类型将是作为模板参数传递给解释器的策略),这意味着value类必须了解解释器,这会使事情稍微复杂一些。

以下是问题:

  • 在这种情况下我该怎么办?为什么
  • "太大"在堆栈上分配的大小是多少?我相信这取决于它的分配频率和复制频率

谢谢。

  • 在这种情况下我该怎么办?为什么

和往常一样,编写程序使其最容易理解如果稍后的评测发现这确实是一个问题,那么您以后总是可以将value::val变成一些动态分配的对象。(当然,这假设val被抽象得足够好,不会影响任何类的客户端。)

  • "太大"在堆栈上分配的大小是多少?我确信这取决于它的分配频率和复制频率

这也取决于你所在的平台。我们谈论的是运行烤面包机的8位嵌入式芯片还是64位工作站
IMO最终归结为:如果它因其尺寸而造成问题,那么它就太大了

如果您确实需要对此进行优化,我建议您不要在Windows上使用std::string

对于不可变的字符串,类似写时复制的实现(基本上,字符串的所有副本共享相同的内部缓冲区)可以很容易地在shared_ptr之上实现。

从那时起,您只需要ConstString类中的一个指针,就不必担心通过副本传递。