创建并返回字符串向量——最有效的解决方案

Create and return a vector of strings - most efficient solution?

本文关键字:有效 解决方案 向量 返回 字符串 创建      更新时间:2023-10-16

在成员函数中,我想返回一个新创建的字符串向量。哪个版本是最有效的内存分配&构造函数调用的观点?theString(i)返回const std::string &

std::vector<std::string> result(depth());
for(int i=0;i<depth;i++) {
    result[i] = theString(i);
}

std::vector<std::string> result;
result.reserve(depth());
for(int i=0;i<depth;i++) {
    result.emplace_back(theString(i));
}

对我来说,似乎是:

  • 解决方案1首先构建每个空字符串,然后复制分配它们=>不完美
  • 解决方案2更好,因为它将复制构造每个字符串,而矢量数据由reserve
  • 分配一次

(或者有没有更有效的解决方案?)

给出一个通用的答案是不可能的:根据您的编译器、您正在使用的标准库实现、目标CPU和周围的源代码,发出的代码可能会有所不同。此外,一种解决方案是否更快还可能受到不同调度引起的缓存效果或线程切换效果的影响。

因此,不幸的是,没有通用的答案:根据您的设置进行测量。

话虽如此,让我提供另外两个候选人;候选人3:

// The simplest code is always easier to read:
std::vector<std::string> result;
for (size_t i = 0; i < depth; ++i) { result.emplace_back(theString(i)); }
如果它比你的候选人差得多,我会很惊讶的。它依赖于vector的平摊常数emplace_back和移动字符串很便宜的事实(与复制相比)。

和候选4:

// If no copy is necessary, then no copy is cheaper:
std::vector<std::string_view> result; // or another "StringRef" alternative
for (size_t i = 0; i < depth; ++i) { result.emplace_back(theString(i)); }

后者依赖于string_view:对字符串的非拥有引用,这是一个非常简单的实现(基本上是一对size_tchar const*),但只有在引用的字符串被保证在string_view的最后使用之后才可行。