C++17 中的 std::string_view 性能远超 std::string - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
zhipengj
V2EX    程序员

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

  •  
  •   zhipengj 2018-09-23 03:12:50 +08:00 9995 次点击
    这是一个创建于 2627 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    img

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

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

    一个小疑问:链接指向的是你自己的 blog 吗?你的这篇帖子的说法容易让人产生“链接不是指向你自己的 blog ”的错觉。
    Valyrian
        2
    Valyrian  
       2018-09-23 06:51:10 +08:00 via iPad
    用的时候条件也比较苛刻,指向的 string 必须全程在 scope 里,除了算 substring 真的没什么鸟用
    PureWhiteWu
        3
    PureWhiteWu  
       2018-09-23 07:45:51 +08:00
    怎么感觉是特意装成不是自己写的一样。。。。
    innoink
        4
    innoink  
       2018-09-23 07:57:56 +08:00 via Android
    这货在 boost 里早就有了 string_ref
    zn
        5
    zn  
       2018-09-23 08:09:02 +08:00 via iPhone
    这博客基本可以肯定是你自己的。那这文章是你自己写的吗?如果文章也是你自己写的,那感觉真是奇怪,毕竟你自己说的是 [周末看到一篇文章] 。难道是“我曾经得了精神分裂症,但是现在我们已经好了”的现实版?
    taowen
        6
    taowen  
       2018-09-23 08:13:48 +08:00
    虽然这么明显的是要推广自己的博客,但是鼓励一下吧。
    skadi
        7
    skadi  
       2018-09-23 09:19:33 +08:00
    "fuck"sv 只是 raw string 引用啊.
    这还要你强调性能么...
    yulon
        8
    yulon  
       2018-09-23 12:32:14 +08:00
    这还用测,只要满足 constexpr 的条件就是零开销,substr 也根本不会分配内存。
    wizardforcel
        9
    wizardforcel  
       2018-09-23 13:43:23 +08:00   1
    ( 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
        10
    wizardforcel  
       2018-09-23 13:48:29 +08:00   1
    @geelaw 测不出来是因为它们都是 constexpr 的,也就是编译时进行的。所以怎么测都是折腾循环变量的时间。。。
    geelaw
        11
    geelaw  
       2018-09-23 19:09:03 +08:00
    @wizardforcel #10 constexpr 并不非要在编译期算出来。
    wizardforcel
        12
    wizardforcel  
       2018-09-23 19:33:55 +08:00 via Android
    geelaw
        13
    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
        14
    geelaw  
       2018-09-24 03:24:55 +08:00
    @geelaw #13 一开始第二个链接的代码有点小错误(没有初始化数组导致 undefined behaviour )。这里是修正的版本:

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

    Oopsy 我搞了一个严重的错误 - - c.cc 的第 8 行我写错了才会导致直接用 char const * 不行,实际上是可以的。我需要收回 13 的后半段。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5097 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 09:21 PVG 17:21 LAX 01:21 JFK 04:21
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86