以较小、更频繁的读取或较大的读取方式读取输入
Reading inputs in smaller, more frequent reads or one larger read
我正在做一个C++教程练习,要求计算文件中的单词数。它让我思考阅读输入的最有效的方法。一次读取整个文件的效率比读取小块(逐行或逐字符(的效率高多少?
答案会根据您执行I/O的方式而变化。
如果您使用的是POSIX open
/read
/close
系列,一次读取一个字节将非常痛苦,因为每个字节将花费一次系统调用。
如果您使用的是C fopen
/fread
/fclose
系列或C++iostream
库,一次读取一个字节仍然不是很好,但效果要好得多。这些库保留一个内部缓冲区,并且只在read
耗尽时调用它。然而,由于您正在为每个字节做一些非常琐碎的事情,每次调用的开销仍然可能使您实际必须进行的每个字节的处理相形见绌。
另一种选择是简单地mmap
整个文件,然后对其进行逻辑运算。您可能注意到,也可能没有注意到,带有和不带有MAP_POPULATE
标志的mmap
之间存在性能差异。同样,你必须测量它然后再看。
I/O最有效的方法是保持数据流动。
也就是说,读取一个512个字符的块比512个1个字符的读取快。您的系统可能已经进行了优化,例如缓存,以加快读取速度,但您仍然有所有这些函数调用的开销。
有不同的方法来保持I/O的流动:
- 内存映射文件I/O
- 双重缓冲
- 特定于平台的API
一些简单的实验应该足以证明。
创建一个1兆字节的矢量或数组
启动计时器
重复1000次:
使用1条读取指令将数据读取到容器中
结束计时器。
重复,使用for循环,读取1000000个字符,每个字符有1条读取指令。
比较您的数据。
详细信息
对于来自硬盘驱动器的每个请求,将执行以下步骤(取决于平台优化(:
- 开始硬盘旋转
- 读取文件系统目录
- 在目录中搜索文件名
- 获取请求字节的逻辑位置
- 寻找给定的轨道&行业
- 将一个或多个扇区的数据读入硬盘
- 将请求的硬盘驱动器内存部分返回到平台
- 降低硬盘驱动器的速度
这称为开销(读取扇区的情况除外(。目标是在硬盘旋转时获得尽可能多的数据传输。启动硬盘驱动器所花费的时间比保持其旋转所需的时间还要长。
- 在线程中读取无符号整数时,c++ 位是否以原子方式切换?
- 如何以滑动窗口方式从 std::bitset 读取位并将它们转换为 int?
- 如何以CV_16UC1的方式读取JPG图像并在屏幕上打印?
- 我可以在中断中写入向量,然后以安全的方式仅在主线程内读取吗?
- Newline更改了C 中打印从文件读取的字符串的方式
- 使用 ffmpeg 以编程方式读取 fMP4
- 最理想的情况是,如果一个变量在多个线程中读取,但只在一个线程中写入,那么它是否应该在写入线程中以非原子方式读取
- 如何使用 c++ 以编程方式读取地理数据
- 在十六进制编辑器中写入程序内存,并以编程方式读取
- C :如何以快速方式读取Char文件
- 使用GetLine和Strtok以某种方式从Istringstream读取
- ifstream是在不使用内存的情况下进行读取的最佳方式
- 读取文本文件而不占用内存的最佳方式
- 无法在 Windows 中以编程方式从其他用户帐户读取文件(C++)
- 从文件中读取大量数据并以有效的方式解析日期.如何提高海量数据的性能
- XE2 - Indy TCPServer:编写和读取列表视图的最佳方式是什么
- Windows 8:如何以编程方式读取用户文档文件夹路径(使用 c)
- 在 Linux 中读取文件的最快方式
- 如何以与字节序无关的方式读取 UTF-16 代码点的长度
- 以较小、更频繁的读取或较大的读取方式读取输入