lea*_*ack 9 c++ performance file-io
我需要编写一个程序,它将在输出文件中写入许多字符.我的程序还需要编写换行符以便更好地格式化.我理解ofstream是一个缓冲流,如果我们使用缓冲流文件io,我们获得了性能.但是,如果我们使用std::endl输出将被刷新,并且由于缓冲输出,我们将失去任何潜在的性能增益.
我想如果我使用'\n'新行,输出将只在我们将要刷新时刷新std::endl.它是否正确?是否有任何技巧可用于在文件输出期间获得性能提升?
注意:我想在文件写入操作完成时刷新缓冲输出.我认为通过这种方式,我可以最小化文件I/O,从而获得性能.
Die*_*ühl 18
通常,如果需要最大性能,流类的用户不应该弄乱流的刷新:当流满时,流内部刷新缓冲区.这实际上比等待所有输出都准备好更有效,特别是对于大文件:缓冲数据在仍然可能在内存中时写入.如果您创建一个巨大的缓冲区,并且只有在虚拟内存系统将部分数据放入光盘而不是文件时才写入.它需要从光盘读取并再次写入.
与此相关的要点std::endl是,人们滥用它会导致缓冲区冲洗,并且他们不知道性能影响.目的std::endl是让人们在合理的点上控制冲洗文件.为了使其有效,他们需要知道他们在做什么.可悲的是,有太多的人不知道std::endl谁宣传它作为一条线的结尾使用它在很多地方使用它是完全错误的.
也就是说,下面是您可能想要尝试提高性能的一些事项.我假设您需要格式化输出(使用std::ofstream::write()不会给你).
std::endl除非必须,否则不要使用.如果编写代码已经存在并且std::endl在许多地方使用,其中一些可能在您无法控制的地方,则可以使用过滤流缓冲区,该缓冲区使用其合理大小的内部缓冲区,并且不会将对其sync()函数的调用转发到基础流缓冲区.虽然这涉及额外的副本,但这比一些虚假的冲洗更好,因为这些是更高的数量级.std::ofstreams std::ios_base::sync_with_stdio(false)产生影响,但调用曾经影响某些实现的性能.如果这会产生影响,您可能希望使用不同的IOstream实现,因为在性能方面可能存在更多错误.std::locale其std::codecvt<...>返回值.这可以通过使用轻松检查.你可以用来获得一个应该是真的.truealways_noconv()std::use_facet<std::codecvt<char, char, stdd::mbstate_t> >(out.get_loc()).always_noconv()std::locale("C")std::localestd::num_put<char>facet 的默认实现仍然可以做你不需要的事情.特别是如果您的数字格式相当简单,即您不继续更改格式标志,您没有替换字符映射(即您不使用有趣的std::ctype<char>方面),等等.使用自定义std::num_put<char>方面可能是合理的:为整数类型创建一个快速但简单的格式化函数并为snprintf()内部不使用的浮点创建一个良好的格式化函数相当容易.有些人建议使用内存映射文件,但这只有在事先知道目标文件的大小时才合理.如果是这种情况,这是一种提高性能的好方法,否则就不值得了.请注意,您可以通过创建std::streambuf使用内存映射接口的自定义,将流格式与内存映射文件(或更常见地,使用任何类型的输出接口)一起使用.我发现内存映射在使用std::istreams 时有时会有效.在许多情况下,差异并不重要.
很久以前我编写了自己的IOStreams和locales实现,它没有遇到上面提到的一些性能问题(可以从我的网站上获得,但它有点陈旧,我已经有近10年未触及它了).有很多事情可以通过这个实现来改进,但我没有最新的实现,我准备在某处发布.很快,希望 - 这是我近10年来一直在思考的事情,尽管......