gpt4 book ai didi

c++ - 使用ofstream缓冲文本输出以获得性能

转载 作者:可可西里 更新时间:2023-11-01 16:27:46 29 4
gpt4 key购买 nike

我需要编写一个程序,该程序将在输出文件中写入许多字符。
我的程序还需要编写换行符以更好地格式化。
我知道ofstream是一个缓冲流,如果我们将缓冲流用于文件io,我们将获得性能。但是,如果我们使用std::endl,则输出将被刷新,并且由于缓冲的输出,我们将失去任何潜在的性能提升。

我想如果我在新行中使用'\n',则仅当我们使用std::endl时,才会刷新输出。这样对吗?在文件输出期间是否有任何技巧可以提高性能?

注意:我想在文件写操作完成时刷新缓冲的输出。我认为通过这种方式,我可以最小化文件I/O,从而获得性能。

最佳答案

通常,如果要获得最大性能,流类的用户不应与流的刷新混为一谈:流在缓冲区已满时会在内部刷新它们的缓冲区。实际上,这比等待所有输出准备好(特别是对于大型文件)要更有效率:在缓冲的数据仍很可能在内存中时写入缓冲的数据。如果创建一个巨大的缓冲区并仅将其写入一次,则虚拟内存系统会将部分数据放到磁盘上,而不是文件放到磁盘上。需要从光盘中读取并重新写入。

关于std::endl的要点是,人们滥用它的行尾导致缓冲区刷新,并且他们不知道性能影响。 std::endl的目的是使人们能够控制在合理的位置刷新文件。为了使此方法有效,他们需要知道他们在做什么。可悲的是,有太多的人不知道std::endl所做的事情,谁宣传它作为行结尾使用,以至于在很多明显错误的地方都使用了它。

就是说,以下是您可能想尝试改善性能的一些事项。我假设您需要格式化的输出(使用std::ofstream::write()不会给您)。

  • 显然,除非必须,否则不要使用std::endl。如果编写代码已经存在并且在许多地方使用了std::endl,其中有些可能不在您的控制范围内,则可以使用过滤流缓冲区,该缓冲区使用其内部缓冲区的大小适当,并且不会将对其sync()函数的调用转发给基础流缓冲区。尽管这涉及额外的拷贝,但这比某些虚假的刷新要好,因为这些虚假的刷新要贵几个数量级。
  • 尽管它不应该影响std::ofstream,但调用std::ios_base::sync_with_stdio(false)会影响某些实现的性能。如果这样做有效果,您可能想使用另一个IOstream实现,因为在性能方面可能存在更多错误。
  • 确保您使用的std::locale在调用std::codecvt<...>true返回always_noconv()。可以使用std::use_facet<std::codecvt<char, char, stdd::mbstate_t> >(out.get_loc()).always_noconv()轻松检查。您可以使用std::locale("C")来获取应该正确的std::locale
  • 一些语言环境实现使用其数值方面的效率很低的实现,即使它们相当好,但std::num_put<char>方面的默认实现可能仍会执行您实际上不需要的操作。尤其是如果您的数字格式相当简单,即您不不断更改格式标志,没有替换字符映射(即您没有使用有趣的std::ctype<char>构面)等,则使用自定义代码可能是合理的std::num_put<char>方面:为整数类型创建快速但简单的格式设置函数,为内部不使用snprintf()的浮点创建良好的格式设置功能相当容易。

  • 有人建议使用内存映射文件,但这仅在事先知道目标文件的大小时才有效。如果是这种情况,这也是提高性能的好方法,否则就不值得花时间了。请注意,可以通过创建使用内存映射接口(interface)的自定义 std::streambuf来将流格式化与内存映射文件(或更常见的是,与任何类型的输出接口(interface)一起)使用。我发现将内存映射与 std::istream一起使用时有时会有效。在许多情况下,差异并不重要。

    很久以前,我编写了自己的IOStreams和语言环境实现,该实现不会受到上述某些性能问题的困扰(可以从 my site获得,但有点陈旧,并且我已经有十多年没有碰过它了) 。在此实现上,仍有很多地方可以改进,但是我还没有最新的实现,因此我准备将其发布到某个地方。希望很快-我将近十年以来一直在思考这个问题...

    关于c++ - 使用ofstream缓冲文本输出以获得性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9425414/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com