在这种情况下,如何决定堆栈、堆和boost::池的分配
How to decide on stack vs heap vs boost::pool allocation in a case like this?
我有一个类,它使用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
类中的一个指针,就不必担心通过副本传递。
- 在 Julia 中使用 boost 库和 Windows 上的 Cxx.jl
- 使用Boost async_read和POSIX::stream_descriptor从键盘读取
- boost信号和插槽在不同的线程中不工作(使用boost::asio::io_service)
- 如何以编程方式区分在内存的堆和堆栈部分创建的对象
- Boost.Python 和导入 dll,"The specified module could not be found"
- 堆和堆栈之间的距离
- 我可以使用 Boost.Asio 和 Boost.Beast 库发出 HTTPS 请求或 HTTP/2 请求吗?
- Boost.Python 和C++导入到 Python 3 时编译库错误
- 使用boost::filesystem和boost::lexical_cast从文件名中提取数字
- 如何通过boost::asio和shared_ptr创建串行端口
- 堆和泄漏摘要
- 使用 Boost ASIO 和 SSL 时出现"Wrong Version Number"错误 (C++)
- boost::regex 和std::regex之间的不一致?
- 配置 Visual Studio 以与 Boost.Python 和 Python 3 配合使用
- 在堆和堆栈中创建对象的差异
- C 使用BOOST.ASIO和BEAST库中的身体发送数据
- “boost::any”和“std::any”之间的区别
- 在 Windows 上使用 Boost python3 和 numpy3 库时,VS2015 中LNK2019未解析的外
- 与 boost.python 和 python3 链接时出现问题
- 在这种情况下,如何决定堆栈、堆和boost::池的分配