`std::string` 分配是我当前的瓶颈 - 如何使用自定义分配器进行优化?

2024-01-07

我正在写一个C++14 JSON 库 https://github.com/SuperV1234/SSVUtils/tree/master/include/SSVUtils/Json作为练习并在我的个人项目中使用它。

通过使用呼叫研磨我发现通过字符串压力测试持续创造价值的当前瓶颈是std::string动态内存分配。 https://github.com/SuperV1234/SSVUtils/blob/master/include/SSVUtils/Json/Io/Reader.hpp#L138-L139准确地说,瓶颈是调用malloc(...)由...制成std::string::reserve.

我读过许多现有的 JSON 库,例如快速JSON https://github.com/miloyip/rapidjson使用自定义分配器来避免malloc(...)在字符串内存分配期间调用。

我尝试分析rapidjson的源代码,但是大量的附加代码和注释,加上我不太确定我在寻找什么,对我没有多大帮助。

  • How do custom allocators help in this situation?
    • 内存缓冲区是否预先分配在某处(在哪里?静态地?)并且std::strings从中获取可用内存?
  • Are strings using custom allocators "compatible" with normal strings?
    • 他们有不同的类型。他们必须“皈依”吗? (这会导致性能下降吗?)

代码注释:

  • Str是一个别名std::string.

默认情况下,std::string根据需要从与您分配的任何内容相同的堆中分配内存malloc or new。为了通过提供您自己的自定义分配器来获得性能提升,您需要以这样的方式管理您自己的内存“块”,以便您的分配器可以比字符串更快地处理您的字符串请求的内存量。malloc做。您的内存管理器将进行相对较少的调用malloc, (or new,取决于您的方法)在引擎盖下,一次请求“大量”内存,然后通过自定义分配器处理此(这些)内存块的部分。实际实现比malloc,您的内存管理器通常必须根据用例的已知分配模式进行调整。

这种事情通常可以归结为内存使用与执行速度之间古老的权衡。例如:如果您在实践中知道字符串大小的上限,则可以通过过度分配来始终适应最大的情况。虽然这会浪费内存资源,但它可以减轻更通用的分配因内存碎片而产生的性能开销。以及拨打任何电话realloc基本上为您的目的提供恒定的时间。

@sehe 是完全正确的。有很多方法。

EDIT:

最后要解决第二个问题,使用不同分配器的字符串可以很好地协同工作,并且使用应该是透明的。

例如:

class myalloc : public std::allocator<char>{};
myalloc customAllocator;

int main(void)
{
  std::string mystring(customAllocator);
  std::string regularString = "test string";
  mystring = regularString;
  std::cout << mystring;

  return 0;
}

这是一个相当愚蠢的示例,当然,在幕后使用相同的主力代码。但是,它显示使用“不同类型”的分配器类在字符串之间进行分配。实现一个有用的分配器,提供 STL 所需的完整接口,而不仅仅是隐藏默认接口std::allocator并不是那么微不足道。This http://www.codeproject.com/Articles/4795/C-Standard-Allocator-An-Introduction-and-Implement似乎是一篇不错的文章,涵盖了所涉及的概念。至少在您的问题的上下文中,这种方法起作用的关键在于,使用不同的分配器不会导致字符串具有不同的类型。请注意,自定义分配器作为构造函数的参数而不是模板参数给出。 STL 仍然使用模板做一些有趣的事情(例如rebind and Traits)以均匀化分配器接口和跟踪。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

`std::string` 分配是我当前的瓶颈 - 如何使用自定义分配器进行优化? 的相关文章

  • 我们可以在 C# 中定义枚举的隐式转换吗?

    是否可以在 C 中定义枚举的隐式转换 可以实现这一目标的东西吗 public enum MyEnum one 1 two 2 MyEnum number MyEnum one long i number 如果没有 为什么不呢 有一个解决方案
  • 您使用什么工具和技术来查找死代码? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 您使用哪些工具和技术来查找 NET 中的死代码 过去 我用 Obsolete 属性修饰方法 传递 tr
  • 运行时两个注册之间的简单注入器基于动态上下文的注入

    我有一个使用 Simple Injector 进行命令处理程序注册的中介应用程序 并且注入和处理程序均已设置并完美运行 class DoWashingCommandHandler IRequestHandler
  • 在异步方法中使用时 HttpClient 标头被清空

    我正在使用 NET Framework 4 6 1 我的 Web api 中有一个控制器 其中有静态 HttpClient 来处理所有 http 请求 在 IIS 上托管我的应用程序后 大约每月一次 我的应用程序的所有传入请求都会出现以下异
  • 外部剃刀视图看不到外部模型

    我对外部剃刀视图有疑问 在我的项目中 我有主 mvc Web 程序集和动态加载的外部类库程序集 来自 DB 及其自己的控制器 视图和模型 这些程序集在运行时不会直接引用和加载 我能够通过为控制器创建自定义控制器工厂 为视图创建自定义虚拟路径
  • 用 C# 中的字典中的值替换字符串中的单词

    我有一个简单的dictionary像这样 var fruitDictionary new Dictionary
  • 在 C/C++ 中绘制填充椭圆的简单算法

    在SO上 找到了以下绘制实心圆的简单算法 for int y radius y lt radius y for int x radius x lt radius x if x x y y lt radius radius setpixel
  • VS2010中VSHost.exe不断启动

    我正在 VS2010 中使用一个包含大量项目的解决方案 但它不断变得无响应 我注意到的一件事可能是一条线索 尽管我尚未开始任何调试 但 MyApplicationName vshost exe 不断出现在进程列表中 也许每当构建发生时它就会
  • 如何在 C++ 中从模板基类的构造函数调用模板超类的构造函数?

    我正在使用 sublimetext3 用 c 进行编程 我的程序有一个名为 Array 的超类和一个名为 IntArray 的子类 这两个类都是模板类 目前 我在编译该程序时遇到问题 它不断在我的 IntArray cpp 文件中给出错误
  • 如何将 QSerialPort 模块添加到 CMake 中?

    我想将 QSerialPort 模块添加到 CMake 中 根据我的理解 我需要将QT 串口添加到 pro中 我只想使用 CMake 所以我尝试编译简单的 CMake 文件 但有错误 QtCore 正在工作 qDebug 可以毫无问题地显示
  • ObjectTrackingEnabled 和 linq-to-sql

    I read here http www sidarok com web blog content 2008 05 02 10 tips to improve your linq to sql application performance
  • 使用私有构造函数的 C# 单元测试类?

    好吧 我刚刚收到一个作业 我必须对具有私有构造函数的类执行单元测试 现在 当所有方法也都是非静态时 我该如何在不初始化类的情况下进行单元测试 有什么方法可以对具有私有构造函数的类进行单元测试 无需反射 如果您无法将类公开 您仍然可以通过以下
  • UWP - 绑定枚举差异

    我遇到了一个非常有趣的问题 假设 UWP 应用中有以下 XAML 页面内容
  • 内存不足异常

    我正在使用 C 和 asp net 开发一个网络应用程序 我一直收到内存不足的异常 该应用程序的作用是从数据源读取一堆记录 产品 可能是数百 数千 通过向导中的设置处理这些记录 然后使用处理的产品信息更新不同的数据源 虽然有多个 DB 类
  • 嘲笑会员用户

    我目前正在开发一个 asp net mvc 2 应用程序 它使用默认的 SqlMembershipProvider 进行身份验证 我已经实现了一个控制器方法 通过调用读取当前用户的 ProviderUserKeyMembership Get
  • 没有类型的 IEnumerable 属性

    我正在尝试创建一个类似于来自 MSDN 的官方 DataGrid ItemsSource 的属性 public IEnumerable ItemsSource get set 这提供了对任何派生类中任何类型的支持 有了这个 我可以设置类似的
  • Subsonic 3 ActiveRecord 嵌套选择导致 NotIn 错误?

    我有以下 Subsonic 3 0 查询 其中包含嵌套的 NotIn 查询 public List
  • Task.Delay 到底是如何工作的?

    他们说 Task Delay 是一个异步 Thread Sleep 为了测试这一点 我写了下面的代码 我希望立即打印 One 然后 3 秒后将打印结果变量 15 2 秒后 将打印 Two 但似乎并非如此 一 不会立即打印 3 秒后打印 On
  • 更快的 WinSock sendto()

    我使用的是 Windows Server 2008 我的程序是用 C 编写的 我在 while true 循环中使用 WinSock2 和 sendto 来发送数据包 代码如下 while true if c snd gt max c sn
  • 有关 Endian 性和 .Net 的详细信息?

    我有几个关于字节顺序的问题 这些问题足够相关 我保证将它们作为一个问题提出 1 字节顺序是由 Net还是由硬件决定的 2 如果是由硬件决定的 我怎样才能在C 中找出硬件的字节序 3 字节序是否影响二进制交互 例如 OR AND OR 或移位

随机推荐