【问题标题】:I wonder about the efficiency of seek我想知道 seek 的效率
【发布时间】:2019-02-16 00:04:26
【问题描述】:

我目前正在研究 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 ~

我想知道这两种方法中哪一种比减去dummy data和读取数据和通过seek读取新数据更有效。

【问题讨论】:

  • (1) BenchmarkTime::HiRes (2) 你展示的东西是无与伦比的:在一种情况下你使用unpack,在另一种情况下你使用read数据; (不管缓冲)您正在比较内存中的工作和磁盘读取?最后一句不清楚。
  • 提示:使用x 而不是A 跳过字节而不返回它们
  • 提示:二进制数据使用a 而不是AA 将删除尾随 0x20 字节
  • 这会给你留下my $data = unpack("x0x78 a*", $buf);
  • 哇,我第一次注意到名为“x”的解包功能。谢谢你告诉我

标签: perl pack seek unpack


【解决方案1】:

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

您的文件跨越两个扇区。

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

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

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


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

也就是说,差异很小,以至于速度差异应该消失在噪音中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多