首先要考虑的是,将存储在输出字符串中的总数据量几乎肯定很小,因此我怀疑其中任何一个都会对性能产生显着影响。我的主要目标是找到一种连接一系列大小未知的 const char*
的方法,这种方法看起来并不糟糕,同时还要牢记效率。以下是我的搜索结果:
方法一:
std::string str = std::string(array1) + array2 + array3;
方法二:
std::string str(array1);
str += array2;
str += array3;
我决定使用第一种方法,因为它简短明了。如果我没记错的话,这两种方法都会调用相同的一系列操作。未优化的编译器将首先创建一个临时字符串并在内部为其缓冲区分配一些空间 >= sizeof(array1)
。如果该缓冲区足够大,则额外的 + 操作将不需要任何新的分配。最后,如果支持移动语义,则交换临时和命名 str
的缓冲区。
有没有其他方法可以执行这样的操作,既好看又不会产生可怕的开销?
请记住,如果是数组,sizeof(array) 返回它的参数的实际大小(又名长度),如果它已被声明为显式大小的数组(并且您写了“series of 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);
我不知道这个解决方案在您看来是否“看起来不错”,但它绝对清楚并且针对此用例进行了优化。