新的 C++ 代码应该使用内存资源而不是分配器吗?
Should new C++ code use memory resources instead of allocators?
C++17 将为我们带来 std::pmr::memory_resource
which is a clean interface for allocating and deallocating memory. Unlike the Allocator concept, it does just that and nothing more. There will also be std::pmr::polymorphic_allocator
,它将内存资源包装到经典分配器中,因此它可以与现有容器一起使用。
如果我要编写一个针对 C++17 及更高版本的新容器(或其他需要大量内存的)类型,我应该继续针对 Allocator 概念进行编程还是而是直接使用更新更清晰的抽象?
到目前为止,我的想法是这样的。
继续使用分配器的原因:
- 与标准库和现有代码一致。即使是新的
std::pmr::*
容器别名也继续使用分配器。
- 由于内存资源可以包装成
std::pmr::polymorphic_allocator
,分配器接口更通用,满足更多客户端的需求。
- 内存资源始终使用 运行 时间多态性,因此与分配器可以提供的零开销抽象相比,它们具有较小的额外 运行 时间开销。
- 也许有人实际上需要纯内存资源无法提供的分配器接口的其他部分(例如自定义指针类型)。
开始使用内存资源而不是分配器的原因:
- 分配器接口笨重且难以实现。
std::pmr::memory_resource
界面简洁明了。
- 由于内存资源是多态的,它们不会影响容器的类型,这意味着更少的模板实例化(因此可能更快的编译和更小的可执行文件)并使我们能够将更多的代码移动到单独的翻译单元中。
- 如果一个对象使用内存资源,它总是可以通过将内存资源包装到
std::pmr::polymorphic_allocator
来实例化一个仍然使用分配器的子对象。反过来就更难了。
- 无论如何,内存分配是一项相对工作密集型的任务。相对而言,单个虚函数调用不会增加太多开销。
关于如何有效使用新库功能是否已经存在任何建议?
此时没有
C++ 中的分配器现在比以前容易得多。
它们同时提供 pmr(多态)和经典分配器支持。
更重要的是,基于 pmr 的分配多年来一直没有大量使用。任何弱点都可能会暴露出来。
基于快速池的分配器,甚至是固定缓冲区分配器或 sbo(小缓冲区优化)扩展,可能会注意到虚拟化开销。
C++17 将为我们带来 std::pmr::memory_resource
which is a clean interface for allocating and deallocating memory. Unlike the Allocator concept, it does just that and nothing more. There will also be std::pmr::polymorphic_allocator
,它将内存资源包装到经典分配器中,因此它可以与现有容器一起使用。
如果我要编写一个针对 C++17 及更高版本的新容器(或其他需要大量内存的)类型,我应该继续针对 Allocator 概念进行编程还是而是直接使用更新更清晰的抽象?
到目前为止,我的想法是这样的。
继续使用分配器的原因:
- 与标准库和现有代码一致。即使是新的
std::pmr::*
容器别名也继续使用分配器。 - 由于内存资源可以包装成
std::pmr::polymorphic_allocator
,分配器接口更通用,满足更多客户端的需求。 - 内存资源始终使用 运行 时间多态性,因此与分配器可以提供的零开销抽象相比,它们具有较小的额外 运行 时间开销。
- 也许有人实际上需要纯内存资源无法提供的分配器接口的其他部分(例如自定义指针类型)。
开始使用内存资源而不是分配器的原因:
- 分配器接口笨重且难以实现。
std::pmr::memory_resource
界面简洁明了。 - 由于内存资源是多态的,它们不会影响容器的类型,这意味着更少的模板实例化(因此可能更快的编译和更小的可执行文件)并使我们能够将更多的代码移动到单独的翻译单元中。
- 如果一个对象使用内存资源,它总是可以通过将内存资源包装到
std::pmr::polymorphic_allocator
来实例化一个仍然使用分配器的子对象。反过来就更难了。 - 无论如何,内存分配是一项相对工作密集型的任务。相对而言,单个虚函数调用不会增加太多开销。
关于如何有效使用新库功能是否已经存在任何建议?
此时没有
C++ 中的分配器现在比以前容易得多。
它们同时提供 pmr(多态)和经典分配器支持。
更重要的是,基于 pmr 的分配多年来一直没有大量使用。任何弱点都可能会暴露出来。
基于快速池的分配器,甚至是固定缓冲区分配器或 sbo(小缓冲区优化)扩展,可能会注意到虚拟化开销。