Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 返回空字符串:c+中的有效方法+;_C++_String_Performance - Fatal编程技术网

C++ 返回空字符串:c+中的有效方法+;

C++ 返回空字符串:c+中的有效方法+;,c++,string,performance,C++,String,Performance,我有两种从函数返回空字符串的方法 (一) (二) 哪一个更有效?为什么 后一个版本永远不会比前一个版本慢。第一个版本调用采用C字符串的std::string构造函数,然后必须首先计算字符串的长度。即使对空字符串这样做很快,但肯定不会比根本不这样做快 Gcc 7.1-O3这些都是相同的,godbolt.org/z/a-hc1d–jterm 4月25日3:27 原始答复: 做了一些挖掘。下面是一个示例程序和相关组件: 代码: 这是用-std=c++11-O2编译的 您可以看到,return''还有很

我有两种从函数返回空字符串的方法

(一)

(二)


哪一个更有效?为什么

后一个版本永远不会比前一个版本慢。第一个版本调用采用C字符串的
std::string
构造函数,然后必须首先计算字符串的长度。即使对空字符串这样做很快,但肯定不会比根本不这样做快

Gcc 7.1-O3这些都是相同的,godbolt.org/z/a-hc1d–jterm 4月25日3:27

原始答复: 做了一些挖掘。下面是一个示例程序和相关组件:

代码:

这是用
-std=c++11-O2
编译的

您可以看到,
return''还有很多工作要做语句,对于
returnstd::string
return{}来说相对较少(这两个是相同的)

正如Frerich Raabe所说,当传递一个空的
C_字符串时,它仍然需要对其进行处理,而不仅仅是分配内存。这似乎无法优化(至少GCC无法优化)

因此,答案是明确使用:

return std::string();


尽管除非在性能关键型代码(我想是日志记录?)中返回大量空字符串,否则差异仍然很小。

两者都不是。使用
返回{}。这与C有什么关系?这属于无用的微优化领域,编译器将使用RVO和复制省略进行优化。@KerrekSB您能详细说明原因吗?因为它是使用默认构造函数直接初始化,而不是复制初始化(从可能动态计算的构造函数)。如果您的实现非常倾向于将默认构造函数实现为无分配constexpr。由于它是一个返回的常量,编译器是否没有优化长度计算?如果不是,可能是吗?@Baldrickk他正在调用
std::string
的单参数构造函数。我不认为有多少(如果有的话)编译器足够聪明,可以推断单参数构造函数等同于同时使用指针和大小的构造函数,只要它传递的值小于字符串文本的大小(后面有一个
'\0'
)。@JamesKanze:一些编译器优化
strlen()在字符串文字上,我要求这个特性在十多年前被添加到SpCcWorksC++中,不知道他们是否曾经这么做过——GCC已经做过了。不过,我并不一定期望C++实现使用<代码>斯特伦< /代码>…“我也不知道。”詹姆斯坎茨证实了你的话。请看我的答案。可能这需要从2017年起进行更新。所有三种可能的返回都会产生相同的asm结果,因此返回“”或std::string{}或{}不会有任何问题。在编译器资源管理器上测试clang&gcc@TomazCanabrava我当时应该注意到gcc版本。。。如果你想提供你测试过的clang和gcc版本,我会在回答中注意到这一点。@TomazCanabrava实际上,当我尝试使用上面的gcc和clang时,我得到了类似的结果(gcc 7.1/clang4.0.0)。有趣的是,Visual studio(2015)提供的结果在每个版本之间都是一致的,但在所有情况下都做了更多的工作是C++扩展,所以<代码>返回STD::StReg();<代码>应该是首选。
std::string get_string()
{
   return std::string();
}
#include <string>

std::string get_string1(){ return ""; }

std::string get_string2(){ return std::string(); }

std::string get_string3(){ return {}; }           //thanks  Kerrek SB

int main()
{
    get_string1();
    get_string2();
    get_string3();
}
__Z11get_string1v:
LFB737:
    .cfi_startproc
    pushl   %ebx
    .cfi_def_cfa_offset 8
    .cfi_offset 3, -8
    subl    $40, %esp
    .cfi_def_cfa_offset 48
    movl    48(%esp), %ebx
    leal    31(%esp), %eax
    movl    %eax, 8(%esp)
    movl    $LC0, 4(%esp)
    movl    %ebx, (%esp)
    call    __ZNSsC1EPKcRKSaIcE
    addl    $40, %esp
    .cfi_def_cfa_offset 8
    movl    %ebx, %eax
    popl    %ebx
    .cfi_restore 3
    .cfi_def_cfa_offset 4
    ret $4
    .cfi_endproc

__Z11get_string2v:
LFB738:
    .cfi_startproc
    movl    4(%esp), %eax
    movl    $__ZNSs4_Rep20_S_empty_rep_storageE+12, (%eax)
    ret $4
    .cfi_endproc

__Z11get_string3v:
LFB739:
    .cfi_startproc
    movl    4(%esp), %eax
    movl    $__ZNSs4_Rep20_S_empty_rep_storageE+12, (%eax)
    ret $4
    .cfi_endproc
return std::string();
return {};   //(c++11)