我有一个使用boost :: variant来存储double或字符串的类,如下所示:
class value
{
boost::variant<double, std::string> val;
};
对于我正在玩的玩具翻译来说,它应该是一个不可变的值类型。 起初,通过const引用传递它并按值返回似乎是一个好主意,并且总是将它分配到堆栈上,因为我希望它被视为基元。然而,然后我看到它的大小是40个字节(由于sizeof std :: string,大多数),我有点担心。我知道我不应该在堆栈上分配大块内存,但是有多大太大了?
另外,每次返回时复制40个字节,特别是因为值是不可变的,甚至不需要复制,看起来有点浪费。
常规堆分配选项看起来不太吸引人,因为我每秒可能有数千个这样的分配/解除分配。
我想出的最后一个选项是让boost :: pool在需要时分配这些对象,并使用boost :: shared_ptr来管理它们的生命周期。但是,因为解释器负责内存分配(内存分配的类型将是作为模板参数传递给解释器的策略),这意味着值类必须知道解释器,这使事情稍微复杂化
所以这些是问题:
感谢。
答案 0 :(得分:4)
- 在这种情况下我该怎么办?为什么?
与往常一样,编写程序以便最容易理解。 如果分析后来发现这确实是一个问题,您可以随后将value::val
转换为某个动态分配的对象。 (当然,这假设val
被抽象得足够好,以免影响任何一类的客户。)
- 在堆栈上分配“太大”有多大?我确信这取决于它的分配频率和复制频率。
这还取决于你所处的平台。我们在谈论运行烤面包机或64位工作站的8位嵌入式芯片吗? IMO最终归结为:如果由于它的大小而产生问题,它太大了。
答案 1 :(得分:0)
如果您确实需要对此进行优化,我建议您不要在Windows上使用std::string
。
对于不可变字符串,可以在shared_ptr
之上轻松实现类似写操作的实现(基本上,字符串的所有副本共享相同的内部缓冲区)。
从那以后,你只需要在ConstString
课程中使用一个指针,你不必担心复制传递。