iostreams很慢。有没有办法加快他们的速度?

时间:2011-01-31 11:55:13

标签: c++ windows visual-c++ iostream

我已经在一段时间内打开和关闭了一个问题,现在列出了超出Windows MAX_PATH限制的文件名。 我正在使用Visual Studio 2008以及我能找到的所有补丁。时间由QueryPerformanceCounter和公司完成。

最新一期出现在以下代码中:

    start = getTime();
    for( vector<wstring>::iterator it = files.begin(); it != files.end(); ++it )
    {
#if USE_COUT
            wcout << setw( 6 ) << it->length() << L": " << *it << endl;  // 1
#else
            wstring x( *it );
            wprintf( L"%6.6d: %s\n", it->length(), x.c_str() );          // 2
#endif
    }
    stop = getTime();

上述循环遍历一个包含6755个条目的向量,平均字符串长度为256个字符。

通过wcout打印的代码大约需要52秒才能使用上面的循环显示向量。使用wprintf的代码在大约1.2秒内打印。

如果我最小化控制台窗口,则printf代码在大约500毫秒内运行,而wcout代码仍然需要大约40秒。

多年来我一直试图喜欢iostreams,但是......我一直在关注这个速度问题。在1993/1994年使用Borland OS / 2编译器时,我们遇到了类似的问题,运行时使用sprintf在大约200毫秒内运行的strstream需要4到6个小时才能完成。

有什么建议让我改变我对iostreams的看法吗?

<小时/> 编辑:
所有关于潮红的谈话让我很好奇 \n字符串中的printf在功能上与std::endl的功能是否相同,因为两者都会导致换行符和刷新值被发送到输出中? IIRC,printf没有\n在某些操作系统上打印,直到填充缓冲区或刷新流,包括过去的Windows。 那么,如果wprintf( "%6.6d: %s\n", length, string )刷新了\n,为什么wprintfwcout一样慢?

感谢您的反馈意见。我希望18年前我开始黑客攻击这些东西了。

4 个答案:

答案 0 :(得分:8)

std::endl行终止符很可能导致性能瓶颈,因为它在放入换行符后刷新流。在所有输出的末尾与'\n'std::wcout << std::flush交换。

start = getTime();
for( vector<wstring>::iterator it = files.begin(); it != files.end(); ++it )
{
        wcout << setw( 6 ) << it->length() << L": " << *it << '\n';  // 1
}
std::wcout << std::flush;
stop = getTime();

答案 1 :(得分:2)

  wcout << setw( 6 ) << it->length() << L": " << *it << endl;  // 1

加速的一种方法是在循环中使用"\n"而不是endl,因为endl不仅仅是换行符!

答案 2 :(得分:1)

优化代码使其更少可能是人类可以跟上文本滚动线的模糊不是很有意义。重新思考这种方法。输出到文本文件,使用HTML或许使其看起来不错,然后启动程序以显示结果。更容易吸引用户的眼球。它也会更快地运行 lot ,没有自动刷新,也没有花时间滚动控制台。现在只有磁盘I / O是你的瓶颈。

答案 3 :(得分:1)

很有可能通过不每次迭代刷新你的流来加速你(使用'\ n'而不是endl),虽然我的猜测是你仍然会发现printf更快。

顺便说一句,你也可以将setw移到你的循环之外。