5

我想知道什么是性能开销

string line, word;
while (std::getline(cin, line))
{
    istringstream istream(line);
    while (istream >> word)
        // parse word here
}

我认为这是c++标记输入的标准方法。

再具体一点:

  • 每行是否复制了三次,首先是 via getline,然后是istream构造函数,最后operator>>是每个单词的 via?
  • 频繁的建设和破坏会istream是一个问题吗?如果我istream在外while循环之前定义,等效的实现是什么?

谢谢!

更新:

等效的实现

string line, word;
stringstream stream;
while (std::getline(cin, line))
{
    stream.clear();
    stream << line;
    while (stream >> word)
        // parse word here
}

使用流作为本地堆栈,推送行并弹出单词。这将摆脱之前版本中可能频繁的构造函数和析构函数调用,并利用流内部缓冲效应(这点正确吗?)。

替代解决方案,可能是扩展 std::string 以支持operator<<and operator>>,或扩展 iostream 以支持某事。喜欢locate_new_line只是在这里集思广益

4

2 回答 2

7

不幸的是,iostreams 不适用于性能密集型工作。问题不是在内存中复制东西(复制字符串很快),而是虚函数调度,可能与每个字符的几个间接函数调用有关。

至于你关于复制的问题,是的,当你初始化一个新的stringstream. getline(字符也可以通过or从流中复制到输出字符串中>>,但这显然是无法避免的。)

使用 C++11 的move工具,您可以消除多余的副本:

string line, word;
while (std::getline(cin, line)) // initialize line
{       // move data from line into istream (so it's no longer in line):
    istringstream istream( std::move( line ) );
    while (istream >> word)
        // parse word here
}

All that said, performance is only an issue if a measurement tool tells you it is. Iostreams is flexible and robust, and filebuf is basically fast enough, so you can prototype the code so it works and then optimize the bottlenecks without rewriting everything.

于 2012-06-09T14:29:50.330 回答
1

当您在块内定义变量时,它将在堆栈上分配。当您离开块时,它将从堆栈中弹出。使用此代码,您可以对堆栈进行大量操作。这也适用于“单词”。您可以使用指针并对指针而不是变量进行操作。指针也存储在堆栈中,但它们指向的位置是堆内存中的一个位置。

此类操作可能会产生创建变量、将其压入堆栈并再次从堆栈中弹出的开销。但是使用指针,您分配一次空间,然后在堆中使用分配的空间。指针也可以比实际对象小得多,因此它们的分配会更快。

如您所见,getLine()方法接受对对象的引用(某种指针),line这使其无需再次创建字符串对象即可使用它。

在您的代码中,line变量word只生成一次,并使用它们的引用。您在每次迭代中创建的唯一对象是ss可变的。如果您不想在每次迭代中创建它,您可以在循环之前创建它并使用它的相关方法对其进行初始化。您可以搜索以找到合适的方法来重新分配它而不使用构造函数。

你可以使用这个:

string line, word ;
istringstream ss ;
while (std::getline(cin, line))
{
    ss.clear() ;
    ss.str(line) ;
    while (ss >> word) {
        // parse word here
    }
}

您也可以使用此参考istringstream

编辑:感谢@jrok 的评论。是的,您应该在分配新字符串之前清除错误标志。这是 str() istringstream::str的参考

于 2012-06-09T13:04:45.503 回答