c++ - 为什么 C++11 使 std::string::data() 添加一个空终止字符?
问题描述
以前这是std::string::c_str()
' 的工作,但从 C++11 开始,data()
也提供了它,为什么将c_str()
' 的空终止字符添加到std::string::data()
?对我来说,这似乎是在浪费 CPU 周期,在 null 终止字符根本不相关且仅data()
使用的情况下,C++03 编译器不必关心终止符,也不需要每次调整字符串大小时都必须向终止符写入 0,但是由于data()
-null 保证,C++11 编译器必须在每次调整字符串大小时浪费循环写入 0,因此它可能会使代码变慢,我想他们有理由添加那个保证,那是什么?
解决方案
这里有两点要讨论:
空终止符的空间
理论上,C++03 实现可以避免为终止符分配空间和/或可能需要执行复制(例如unsharing)。
但是,所有理智的实现都为空终止符分配了空间以支持c_str()
开始,因为否则如果这不是一个微不足道的调用,它将几乎无法使用。
空终止符本身
确实,一些非常(1999)、非常古老的实现(2001)编写了\0
每次c_str()
调用。
然而,在 C++11 发布之前,主要实现发生了变化(2004 年)或已经改变了(2010 年),以避免这种事情发生,所以当新标准到来时,对于许多用户来说,什么都没有改变。
现在,无论 C++03 实现是否应该这样做:
对我来说,这似乎是在浪费 CPU 周期
并不真地。如果您c_str()
不止一次调用,那么您已经通过多次编写而浪费了周期。不仅如此,您还弄乱了缓存层次结构,这在多线程系统中很重要。回想一下,多核/SMT CPU 开始出现在2001 年和2006 年之间,这解释了向现代非 CoW 实现的转变(即使在那之前的几十年里有多 CPU 系统)。
唯一可以保存任何东西的情况是,如果您从未调用过c_str()
. 但是,请注意,当您重新调整字符串的大小时,无论如何您都在重新编写所有内容。一个额外的字节将很难测量。
换句话说,如果没有在重新调整大小时编写终结符,您将自己暴露在更差的性能/延迟中。通过同时编写一次,您必须执行字符串的副本,性能行为更加可预测,并且如果您最终使用 ,您可以避免性能缺陷c_str()
,特别是在多线程系统上。
推荐阅读
- c# - Qlik Desktop - 自定义连接器 - ExtractQuery 和其他问题上的错误
- sql - 集团历史数据
- android - 任务:app:bundleReleaseJsAndAssets 失败 - React Native - Android
- multinomial - 多项 logit 模型的 dimnames(x) 错误
- c# - EF 6.4 单元测试对框架运行正常,但 dotnet 5.0 找不到我的连接字符串
- powershell - 将文件夹/子中的所有最新文件复制到powershell中的同名文件夹/子中
- excel-formula - Excel动态数组公式创建列的运行积
- java - 是否可以手动对 Firebase 自动生成的键进行排序?
- javascript - React.js 状态过滤错误。(无法读取未定义的属性“toLowerCase”)
- numpy - 将所有元素左侧的索引设置为 1,将索引右侧的索引设置为零以获取索引列表