【问题标题】:Optimizing unnecessary string copying in vector<string>优化 vector<string> 中不必要的字符串复制
【发布时间】:2011-11-26 13:38:12
【问题描述】:

提供描述问题的最少代码:

struct A {
  vector<string> v;
  // ... other data and methods
};
A obj;
ifstream file("some_file.txt");
char buffer[BIG_SIZE];
while( <big loop> ) {
  file.getline(buffer, BIG_SIZE-1);
  // process buffer; which may change its size
  obj.v.push_back(buffer);  // <------- can be optimized ??
}
...

这里 2 次​​strong> string 创建发生; 第一次创建实际的string 对象,第二次为vector 复制构造它。 Demo

push_back() 操作发生 数百万次,而我多次支付额外的分配费用,这对我没有用处。

有没有办法优化这个?我愿意接受任何合适的改变。 (不将此归类为过早优化,因为push_back() 在整个代码中发生了很多次)。

【问题讨论】:

  • 使用字符串指针向量?
  • @GWW,我对此持开放态度;但是vector&lt;char*&gt; 会比vector&lt;string*&gt; 更好,因为;一旦缓冲区存储在vector 中,我的设计就不会改变。另外,想知道是否有更好的主意。
  • 你可以使用 C++11 移动语义吗?如果是这样,请这样做。
  • @GMan,很遗憾不可能。代码应符合 C++03。否则std::move with rref 应该是我的首选。
  • 在您的演示中,您不是从向量构造函数获得一个分配,而从字符串构造函数获得另一个分配吗?

标签: c++ optimization vector dynamic-allocation


【解决方案1】:

您可以尝试几件事。第一个显然是在编译器上启用优化。 如果您可以将其声明为 vector&lt;const string&gt; 可能会有所帮助。

否则你可能会尝试类似:

obj.v.resize(obj.v.size()+1);
obj.v.back().swap(string(buffer));

【讨论】:

  • 这本质上是 C++03 程序员模拟移动语义的方式。
  • vector&lt; const string &gt;?这合法吗?
  • @K-ballo:不,不是。类型必须是可复制分配的,const string 不满足。
  • 这看起来会扰乱vector的正常增长策略。使用push_back(std::string());来增长向量不是更好吗?
【解决方案2】:

好吧,你得到了两个分配,但不是两个都属于字符串:其中一个创建字符串,而另一个只在向量内部创建一个指针(请注意,这取决于编译器:一些编译器/设置可能确实会创建两个字符串,但大多数不会)。观看this code 的演示。

优化它的一种方法是使用 char* 而不是字符串作为模板参数(不要忘记在终止向量之前手动删除它!)。这样,您将摆脱一个(最大的)分配。或者,只需使用您自己的向量实现:您将能够控制内存分配的各个方面。

【讨论】:

    【解决方案3】:

    不要在堆栈上放置缓冲区,而是将其放在堆上。然后使用指针向量。只有一个

    【讨论】:

      猜你喜欢
      • 2021-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多