3

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

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

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

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

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

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

所以这些是问题:

  • 在这种情况下我应该怎么做,为什么?
  • 在堆栈上分配“太大”有多大?我敢肯定,这取决于分配的频率以及必须复制的频率。

谢谢。

4

2 回答 2

4
  • 在这种情况下我应该怎么做,为什么?

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

  • 在堆栈上分配“太大”有多大?我确信这取决于分配的频率以及必须复制的频率。

这也取决于您使用的平台。我们是在谈论运行烤面包机的 8 位嵌入式芯片还是 64 位工作站?
IMO最终归结为:如果由于其尺寸而产生问题,那就太大了。

于 2011-06-07T13:14:51.247 回答
0

如果你真的需要优化这个,我建议不要std::string在 Windows 上使用。

对于不可变字符串,可以轻松地在shared_ptr.

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

于 2011-06-07T13:28:15.397 回答