5

With std::string_view,range::for_each产生与两者的精确组装const char[N]const char *传递给std::string_viewctor

换句话说,这段代码

auto str = "the quick brown fox is jumping on a lazy dog\nthe quick brown fox is jumping on a lazy dog\n";
ranges::for_each(std::string_view{str}, std::putchar);

auto& str = "the quick brown fox is jumping on a lazy dog\nthe quick brown fox is jumping on a lazy dog\n";
ranges::for_each(std::string_view{str}, std::putchar);

两者都低于装配:

main:                                   # @main
        pushq   %rbx
        movq    $-90, %rbx
.LBB0_1:                                # =>This Inner Loop Header: Depth=1
        movsbl  .L.str+90(%rbx), %edi
        movq    stdout(%rip), %rsi
        callq   _IO_putc
        addq    $1, %rbx
        jne     .LBB0_1
        xorl    %eax, %eax
        popq    %rbx
        retq
.L.str:
        .asciz  "the quick brown fox is jumping on a lazy dog\nthe quick brown fox is jumping on a lazy dog\n"

此外,如果我们将 ac 字符串传递const char[N]ranges::view::c_str()

auto& str = "the quick brown fox is jumping on a lazy dog\nthe quick brown fox is jumping on a lazy dog\n";
ranges::for_each(ranges::view::c_str(str), std::putchar);

这会产生上面的精确装配,就像一个std::string_view生产一样。


另一方面,如果我们传递 acconst char*字符串ranges::view::c_str()

auto str = "the quick brown fox is jumping on a lazy dog\nthe quick brown fox is jumping on a lazy dog\n";
ranges::for_each(ranges::view::c_str(str), std::putchar);

这次它产生了一个不同的程序集,如下所示:

main:                                   # @main
        pushq   %rbx
        movb    $116, %al
        movq    $-90, %rbx
.LBB0_1:                                # =>This Inner Loop Header: Depth=1
        movsbl  %al, %edi
        movq    stdout(%rip), %rsi
        callq   _IO_putc
        movzbl  .L.str+91(%rbx), %eax
        incq    %rbx
        jne     .LBB0_1
        xorl    %eax, %eax
        popq    %rbx
        retq
.L.str:
        .asciz  "the quick brown fox is jumping on a lazy dog\nthe quick brown fox is jumping on a lazy dog\n"

哪个大会获胜?

为什么std::string_view决定产生相同的二进制文件?

只能用和view::c_str()产生一个更快的组装吗?const char*const char [N]

godbolt.org/g/wcQyY1

4

1 回答 1

5

两个std::string_view版本都调用相同的构造函数,它接受 aconst char*然后使用std::char_traits::length(基本上是strlen)来查找长度。编译器优化掉了,strlen因为字符串文字对编译器是可见的,所以它的长度是已知的,但是两种形式都使用完全相同的构造函数,并且都优化掉了strlen,因此两者都生成相同的代码。

view::c_str版本使用不同的重载,具体取决于它是给定指针还是数组,请参阅https://github.com/ericniebler/range-v3/blob/1f4a96e9240786801e95a6c70afebf27f04cffeb/include/range/v3/view/c_str.hpp#L68

当给定一个指针时,它必须找到类似于 using 的长度strlen,但是当给定一个大小数组时,N它使用N-1长度。即使编译器将strlen-like 代码优化为固定的编译时间值,它仍然在编译不同的东西,因此生成的代码不相同也就不足为奇了。

于 2018-03-06T17:58:06.660 回答