高效的const char *连接和输出到std :: string

时间:2013-12-18 03:27:28

标签: c++ string c++11

首先考虑一下,将存储在输出字符串中的总数据量几乎肯定很小,因此我怀疑其中任何一项都会对性能产生明显影响。我的主要目标是找到一种方法来连接一系列未知大小的const char*,这些方法看起来并不可怕,同时还要考虑到效率。以下是我的搜索结果:

方法1:

std::string str = std::string(array1) + array2 + array3;

方法2:

std::string str(array1);
str += array2;
str += array3;

我决定采用第一种方法,因为它简洁明了。如果我没有弄错的话,两种方法都会调用同一系列的操作。未经优化的编译器将首先创建一个临时字符串,并在内部为其缓冲区> = sizeof(array1)分配一些空间。如果该缓冲区足够大,则额外的+操作将不需要任何新的分配。最后,如果支持移动语义,则交换临时和命名str的缓冲区。

还有其他方法可以执行这样一个看起来不错且不会产生可怕开销的操作吗?

1 个答案:

答案 0 :(得分:1)

请记住,在数组的情况下,sizeof(array)返回它的参数的实际大小(也就是长度),如果它已被声明为显式大小的数组(并且你写了'const char *的系列'未知大小')。因此,假设您想要创建通用解决方案,则应该考虑使用strlen()。

我认为你不能避免所有额外的操作。在多个连接的情况下,最好的解决方案是分配缓冲区,该缓冲区足够大以存储所有连接的字符串。

我们可以很容易地推断,在这种情况下,append()的最佳版本是:

string& append (const char* s, size_t n);

为什么呢?因为引用说:'如果s没有指向一个足够长的数组(...),它会导致未定义的行为'。所以我们可以假设,内部没有进行额外的检查(特别是额外的strlen()调用)。哪个好,因为你完全确定,传递给append()的值是正确的,你可以避免不必要的开销。

现在,实际的连接可以这样完成:

len_1 = strlen(array_1);
len_2 = strlen(array_2);
len_3 = strlen(array_3);

//Preallocate enough space for all arrays. Only one reallocation takes place.
target_string.reserve(len_1 + len_2 + len_3);

target_string.append(array_1, len_1);
target_string.append(array_2, len_2);
target_string.append(array_3, len_3);

我不知道这个解决方案在您看来是否“看起来不错”,但它绝对清晰,并针对此用例进行了优化。

相关问题