3

假设在硬盘上我有一些非常大的字符序列数据文件:

阿布兹....

我的问题如下,如果头部位于文件的开头,并且我需要每 1000 个位置间隔 5 个字符,最好是做一个 Seek (因为我知道在哪里看)或者只是有一个大缓冲区只是顺序读取然后在内存中完成工作。

我天真地回答说,阅读“A”然后寻求阅读“V”比 >> 阅读所有文件直到位置 200(“V”的位置)要快。好的,这只是一个例子,因为最小的 I/O 是 512 字节。

编辑:我之前的自我天真回答在以下情况下得到了部分证明:给定一个 100Gb 的文件,我需要第一个和最后一个字符;在这里,我显然会寻求....对吗?

也许在搜索“多长时间”与要检索多少数据之间进行权衡?

有人可以向我澄清这一点吗?

4

1 回答 1

0

[更新] 通常,如果您的步数小于您的块大小的 2 倍,则每 1000 个中的 5 个(假设 5 个字节是 1000 的一部分,因此使您的步数为 1000)答案是一个很好的解释。一旦超过 HD 块大小的 2 倍,它确实会变得更加棘手,因为那时,您很容易浪费读取时间,而您可以通过寻找过去未使用的(或就此而言不必要的)来加速) 高清块。

[原创] 嗯,这是一个非常有趣的问题,我相信这是一个同样有趣的答案(也有些复杂)。我认为这实际上归结为其他几个问题,例如您在驱动器(或您的软件将要运行的驱动器)上实现的块大小有多大。如果您的块大小为 4KB,那么您的硬盘驱动器一次将为您获得的(真实)最小值是 4096 字节。在您的情况下,如果您确实每 1000 个字符需要 5 个字符,那么如果您使用所有磁盘 IO 执行此操作,那么您实际上将重新读取相同的块 4 次,并在其间进行 3 次查找(真的没有效率)。

我个人的信念是,您可以(如果您想提高驱动效率)在您的代码中,尝试了解您正在使用的驱动器的块大小是多少,然后使用该大小数字来了解您一次有多少字节应带入 RAM。这样你就不必有一个巨大的 RAM 缓冲区,但同时也不必真正地寻找,你不会浪费(或执行)任何额外的读取。

这是最有效的吗?我不认为它是最有效的,但它可能足以满足您需要的性能,谁知道呢。我确实认为,即使读取头在您想要的位置,如果您在每个块读取的中间执行算法工作,而不是一次读取整个文件,您将浪费时间等待驱动盘片的下一次旋转。然而,如果您要一次读取所有文件,则驱动器应该能够一次对文件的所有部分执行顺序读取。再次不是那么简单,就像您的文件确实超过 1 个块一样,在旋转驱动器上,如果您的驱动器没有进行碎片整理,您可能会受到影响,因为它可能必须执行随机搜索才能到达下一个块。

抱歉,对于冗长的答案,但通常情况下,您的情况没有简单的答案。

我确实认为,如果您一次读取整个文件,整体性能可能会更好。无法确保这一点,因为每个系统的驱动器设置等参数都不同......

于 2012-06-11T15:55:20.520 回答