C++17 中的 std::string_view 性能远超 std::string

2018-09-23 03:12:50 +08:00
 zhipengj

周末正好看到一篇文章,讲 std::string_view 的性能,对于一些函数,其执行效率远远高于传统的 std::string。

Use std::string_view to avoid string copy in C++17

性能之所以这么好,很大程度上是由于 string_view 只提供了对原数据不可修改的指针,跳读的效率是远高于 string 的。

附上其中一个 substr 操作的 benchmark 结果:

9523 次点击
所在节点    程序员
15 条回复
geelaw
2018-09-23 04:41:46 +08:00
比较严重的错误:你写的那种从 char const * 构造 string_view 的写法并不是 O(1) 而是 Omega(length),因为你构造的时候就计算长度了。在很多情况下你看不出这个错误,是因为使用者通常也用了 Omega(n) 的时间。

不是很严重的错误:一些拼写错误。

一个小疑问:链接指向的是你自己的 blog 吗?你的这篇帖子的说法容易让人产生“链接不是指向你自己的 blog ”的错觉。
Valyrian
2018-09-23 06:51:10 +08:00
用的时候条件也比较苛刻,指向的 string 必须全程在 scope 里,除了算 substring 真的没什么鸟用😂
PureWhiteWu
2018-09-23 07:45:51 +08:00
怎么感觉是特意装成不是自己写的一样。。。。
innoink
2018-09-23 07:57:56 +08:00
这货在 boost 里早就有了 string_ref
zn
2018-09-23 08:09:02 +08:00
这博客基本可以肯定是你自己的。那这文章是你自己写的吗?如果文章也是你自己写的,那感觉真是奇怪,毕竟你自己说的是 [周末看到一篇文章] 。难道是“我曾经得了精神分裂症,但是现在我们已经好了”的现实版?
taowen
2018-09-23 08:13:48 +08:00
虽然这么明显的是要推广自己的博客,但是鼓励一下吧。
skadi
2018-09-23 09:19:33 +08:00
"fuck"sv 只是 raw string 引用啊.
这还要你强调性能么...
yulon
2018-09-23 12:32:14 +08:00
这还用测,只要满足 constexpr 的条件就是零开销,substr 也根本不会分配内存。
wizardforcel
2018-09-23 13:43:23 +08:00
( 1 )应该用 "..."s 和 "..."sv 来构造这些东西,把开销放在编译时间,省不少事。

( 2 )其实翻翻文档,你就知道它在干嘛了:

string_view::string_view(const string_view&) 是 default

https://zh.cppreference.com/w/cpp/string/basic_string_view/basic_string_view


string_view::operator =(const string_view&)和 substr 复杂度为常数

https://zh.cppreference.com/w/cpp/string/basic_string_view/operator%3D

https://zh.cppreference.com/w/cpp/string/basic_string_view/substr
wizardforcel
2018-09-23 13:48:29 +08:00
@geelaw 测不出来是因为它们都是 constexpr 的,也就是编译时进行的。所以怎么测都是折腾循环变量的时间。。。
geelaw
2018-09-23 19:09:03 +08:00
@wizardforcel #10 constexpr 并不非要在编译期算出来。
wizardforcel
2018-09-23 19:33:55 +08:00
geelaw
2018-09-24 03:20:07 +08:00
@wizardforcel #12 你的链接里的说明已经告诉你了。

“ constexpr 指定符声明可以在编译时求得函数或变量的值。”

只是可以,并没有要求必须计算出来。完整的标准里也没有要求 constexpr 必须在编译期计算出来。实际的实现也不一定。

下面是 Visual C++ Compiler (cl.exe) 19.15.26726 for x64 的实验 http://codepad.org/Yw4Q8FNn

另一个你没注意到的错误是,字符串字面量作为 char const * 传入 constexpr 函数的时候永远不会有 constexpr 的效果。正确的实现是使用数组并用模板参数控制数组长度,当然为了兼容进来的是指针、数组、空指针等等各种情况,你需要用偏特化。下面的代码是一个范例:

http://codepad.org/MSqAmd5R
geelaw
2018-09-24 03:24:55 +08:00
@geelaw #13 一开始第二个链接的代码有点小错误(没有初始化数组导致 undefined behaviour )。这里是修正的版本:

http://codepad.org/X2D62VwD
geelaw
2018-09-24 05:53:31 +08:00
@wizardforcel
@geelaw
@geelaw #12 #13 #14

Oopsy 我搞了一个严重的错误 - - c.cc 的第 8 行我写错了才会导致直接用 char const * 不行,实际上是可以的。我需要收回 13 的后半段。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/491861

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX