我想知道seek的效率

I wonder about the efficiency of seek

我正在研究PE结构。 我正在尝试使用 perl 而不是 C 来解析它。

这不是什么重要的事情,但是如果你读一个二进制文件,你必须跳到某个部分。 (比如读e_lfanew)

我要读取0x78点的数据,$buf读取0x200数据

下面是我想到的两种提取0x78处数据的方法。

my ($ dummy, $ data) = unpack ("A0x78 A*", $buf);
or
seek (F, 0x78,0); read F, $buf, 0x200; print ~

我想知道这两种方法中哪种方法比减去虚拟数据和读取数据以及通过seek读取新数据更有效。

一个驱动器的最小存储单元叫做sector。对于硬盘驱动器,这些驱动器的大小通常为 512 字节(尽管您也可以找到具有 4096 字节扇区的驱动器)。

您的文件跨越两个扇区。

000  078       200   278      400
+--------------+--------------+---...
|    ****************
+--------------+--------------+---...

并且由于感兴趣的块部分位于第一个扇区,因此您描述的两种方法都需要读取相同数量的扇区。

由于实际从磁盘读取数据是较慢的部分,因此这两种方法之间没有真正的区别。


哦,但是你是缓冲 IO 而不是使用 sysread。当使用缓冲 IO(例如 read)时,Perl 从 OS 中读取 4 KiB 或 8 KiB 块(取决于您的 Perl 版本)。因此,如果您从位置 0 开始读取,则从磁盘加载 8 或 16 个扇区,如果您先 seek,则从磁盘加载 9 或 17 个扇区。因此,通过尝试减少阅读,您实际上正在阅读更多!

也就是说,差异足够小,速度差异应该在噪音中消失。