C ++:提高ifstream二进制文件的读取速度

时间:2013-10-18 02:22:20

标签: php c++ performance stl iostream

我正在将小程序从PHP重写为C ++。这个想法基本上是通过SSD读取32Gb文件并对其进行一些简单的操作。

我正在使用带有x64版本构建的Visual Studio 2012。 PHP是5.3 32位。

问题是PHP中的裸读速度比C ++中的高,这真的让我感到困惑。 PHP大约350 Mb / s,C ++ / ifstream代码大约180 Mb /秒。

代码非常简单:

ifstream datafile("data.txt", ios::binary);

while(datafile.read((char*)buffer, data_per_chunk)) {
//  do stuff;

我尝试过不同的缓冲区大小,最高可达16Mb,但差别不大。我也尝试通过datafile.rdbuf() - > pubsetbuf(...)设置内部缓冲区,但它也没有什么区别。

有没有关于如何在不恢复古老的C级界面的情况下加速ifstream的任何提示?我想至少达到PHP级别的性能。也许一些花哨的预读/缓存设置或其他东西。

据我所知,内存映射文件可能会有所帮助,但是如果可以保持简单,只要文件明显大于物理RAM且大于4Gb即可,那么它更愿意调整ifstream的设置。 -bit build。

2 个答案:

答案 0 :(得分:3)

即使使用ifstream,您也可以达到最大的SSD读取速度。

为此,您需要将内部ifstream readbuffer设置为~2Mb,这是峰值SSD读取速度发生的地方,同时适合CPU的L2缓存。然后,您需要以小于内部缓冲区的块读出数据。我在8-16kB块中读取数据得到了最好的结果,但它比读取1Mb块的速度快了约1%。

设置ifstream内部缓冲区:

ifstream datafile("base.txt", ios::binary);
datafile.rdbuf()->pubsetbuf(iobuf, sizeof iobuf);

通过所有这些调整,我获得了495 Mb / sec的读取速度,接近M500 480Gb SSD的理论最大值。在执行期间,CPU负载为5%,这意味着它并未受到ifstream实现开销的限制。

我发现ifstream和std :: basic_filebuf之间没有可观察到的速度差异。

答案 1 :(得分:1)

当你将它全部读入缓冲区时,我没有看到使用ifstream的意义。 basic_filebuf或“古老”C接口都可以使用。您需要先将ifstream与C接口进行比较,以便了解它真的是ifstream的责任。

为了提高性能,我看到了以下选项:

  • std::ifstreamread
  • std::basic_filebufopensgetn
  • Cfopenfread
  • WinApiCreateFile OpenFile!),ReadFileEx等。

也许PHP没有在内部使用C接口,但是winapi,这就是差异的来源。