【问题标题】:Create and return a vector of strings - most efficient solution?创建并返回一个字符串向量 - 最有效的解决方案?
【发布时间】:2014-05-11 17:26:53
【问题描述】:

在成员函数中,我想返回一个新创建的字符串向量。 从内存分配和构造函数调用的角度来看,哪个版本最有效? 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 分配一次

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

【问题讨论】:

  • 哪个代码 sn-p 更容易维护,或者在寻找错误时忽略,等等
  • 我想您的编译器会将两者优化为相同的代码,检查两者的程序集输出,看看是否有任何差异。正如 Alf 提到的,可读性远比这些微优化更重要。所以选择最容易阅读和维护的东西。
  • 嗯,可读性没有太大区别,绝对是在速度临界区。
  • The Rules of Optimization Club 应用第二条规则。
  • @shuttle87:实际上,这不太可能。但它是否会影响速度是另一个问题。

标签: c++ vector construct


【解决方案1】:

不可能给出一个通用的答案:根据您的编译器、您使用的标准库实现、目标 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)); }

如果它比您的候选 2 差得多,我会感到惊讶。它依赖于 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: a non-owning reference to a string,这是一个非常简单的实现方式(基本上是一对size_tchar const*),但只有在保证引用的字符串比@987654329 的最后一次使用寿命更长的情况下才可行@。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    相关资源
    最近更新 更多