读取较小,较频繁读取或一次较大读取的输入

时间:2014-07-25 17:22:01

标签: c++ io

我正在进行一项C ++教程练习,要求计算文件中的单词数。它让我想到了阅读输入的最有效方法。一次读取整个文件比读取小块(逐行或逐字符)更有效率吗?

2 个答案:

答案 0 :(得分:2)

答案会根据您进行I / O的方式而改变。

如果您使用的是POSIX open / read / close系列,那么一次读取一个字节将会非常难以忍受,因为每个字节都会花费一个系统调用。

如果您使用的是C fopen / fread / fclose系列或C ++ iostream库,则一次读取一个字节仍然不是很好,但它好多了。这些库保留一个内部缓冲区,只在它运行干燥时调用read。但是,由于您为每个字节执行的操作非常简单,因此每次调用开销仍然可能使您实际需要执行的每字节处理相形见绌。但要衡量它并亲自看看。

另一种选择是简单地mmap整个文件,然后就此做你的逻辑。您可能会,也可能不会注意到mmapMAP_POPULATE标志之间的性能差异。同样,你必须测量并看到它。

答案 1 :(得分:0)

最有效的I / O方法是保持数据流动。

也就是说,读取一个512个字符的块比读取1个字符的512个块快。您的系统可能已经进行了优化(例如缓存)以使读取速度更快,但您仍然需要所有这些函数调用的开销。

有不同的方法来保持I / O流动:

  • 内存映射文件I / O
  • 双缓冲
  • 特定于平台的API

一些简单的实验应该足以进行演示。

创建1兆字节的向量或数组 启动计时器 重复1000次:
  使用1条读取指令将数据读入容器 结束计时器。

使用for循环重复读取1,000,000个字符,每个字符读取1条指令。

比较您的数据。

<强>详情
对于来自硬盘驱动器的每个请求,将执行以下步骤(取决于平台优化):

  • 开始硬盘旋转。
  • 读取文件系统目录。
  • 在目录中搜索文件名。
  • 获取所请求字节的逻辑位置。
  • 寻找给定的音轨&amp;扇区。
  • 将1个或多个数据扇区读入硬盘驱动器内存。
  • 将请求的硬盘内存部分返回平台。
  • 旋转硬盘。

这称为开销(除非它读取扇区)。 目标是在硬盘驱动器旋转时获取尽可能多的数据。启动硬盘需要花费更多时间,而不是让它继续旋转。