【问题标题】:iostreams slow. Is there a way to speed them up?iostreams 慢。有没有办法加快他们的速度?
【发布时间】:2011-06-18 13:03:58
【问题描述】:

我几天来一直在破解一个问题,该问题列出了超过 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 编译器时,我们遇到了类似的问题,即使用 strstream 需要 4 到 6 个小时才能完成运行,而使用 sprintf 运行大约需要 200 毫秒。

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


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

感谢您的反馈/意见。我希望我在 18 年前开始研究这些东西时就拥有了 SO。

【问题讨论】:

  • 速度慢的可能是实际的控制台,而不是您的程序。如果您将输出重定向到文件 yourprogram &gt;file.txt 或写入实际文件而不是 wcout ,您会得到任何加速吗?
  • 如果使用\n 而不是endl,性能会怎样?
  • @nos:这大大加快了速度。重定向时缩短到 2 秒。我可能必须将它处理成一个批处理文件,以便使用它的计算机文盲不必求助于命令行重定向:) 谢谢
  • @Charles Bailey:只要隐藏控制台窗口,就可以显着减少时间。如果控制台窗口没有隐藏,它会快 800 毫秒到 1 秒,这看起来很奇怪。谢谢。
  • @JimR:您能否明确说明您的时间安排。多少是显着的?你的意思是如果控制台没有隐藏,使用'\n'需要40s +(0.8s ~ 1s)?

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


【解决方案1】:

std::endl 行终止符很可能会导致性能瓶颈,因为它会在放入换行符后刷新流。在所有输出的末尾用'\n'std::wcout &lt;&lt; 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();

【讨论】:

  • 谢谢,这加快了速度。
【解决方案2】:
  wcout << setw( 6 ) << it->length() << L": " << *it << endl;  // 1

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

【讨论】:

    【解决方案3】:

    优化代码以使其减少人类能够跟上文本滚动行模糊的可能性并没有多大意义。重新考虑这种方法。输出到一个文本文件,也许使用 HTML 让它看起来不错,然后启动一个程序来显示结果。更容易在您的用户的眼睛。它的运行速度也会很多,不会自动刷新,也不会花时间滚动控制台。现在只有磁盘 I/O 是您的瓶颈。

    【讨论】:

    • 程序在最后给出了一些用户主要想看到的概要信息。文件名在那里,因此他可以在必要时参考它们。控制台的回滚大小设置为最大(9999 行),这就是他想要的,所以......这就是他得到的。
    【解决方案4】:

    通过不每次迭代都刷新流(使用 '\n' 而不是 endl)很可能会大大加快您的速度,尽管我猜您仍然会发现 printf 更快。

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

    【讨论】:

    • setw移到循环外意味着它只会在第一次迭代中应用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 2022-01-28
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    相关资源
    最近更新 更多