fseek 的性能开销是多少?

4

fseek 会有性能开销吗?比如,fseek 调用是否实际请求内核移动磁盘头?

此外,fseek 的性能成本与其所寻求的位置有关吗?例如,fseek(1byte) v.s. fseek(100Mb) v.s. fseek(end-of-file)。


1
这实际上取决于底层的层次结构。文件系统、物理介质等等。实际上,它除了在内存中更改一些数字之外,不必做任何事情。实际的读/写操作才是真正有所区别的。 - Eugene Sh.
1
这很可能是微不足道的,与寻求距离无关,但你不会得到任何明确的答案。你能做的最好的事情就是自己测量它,即使这样,你也不能保证你在自己的系统上测量到的结果会与在另一个系统中测量到的结果相近。(但它很可能在任何情况下都是微不足道的,与距离无关。) - Mike Nakis
1
在几乎所有类型的设备上,开销都是可以忽略不计的。 - Barmar
当且仅当存在未被缓存的实际读取时,磁盘头才会移动。如果您发出多个fseek指令而没有实际读取,为什么磁盘头会移动呢? - Weather Vane
1
fseek() 调用存在隐含的成本 - 如果 FILE * 与之相关联的缓冲区处于写模式,则该缓冲区可能会被刷新,如果处于读模式,则可能会被使无效。诸如随机小读取之类的 IO 模式很可能会导致显着的额外读取开销,因为每个 fseek()/读取周期都需要重新填充缓冲区。fseek() 的“距离”和性能影响可能重要,也可能不重要。这将取决于页面缓存命中以及磁盘头移动的距离。这取决于许多,许多事情。 - Andrew Henle
“fseek调用实际上会请求内核移动磁头吗?”--那是不合逻辑的。磁盘被许多用户和进程访问。除非每个其他访问都被锁定,否则一个进程的任何寻道操作而没有读取或写入操作可能都是浪费时间。此外,ATAPI的当前版本已经弃用了寻道命令。寻道只能隐含在读取或写入命令中。 - sawdust
1个回答

1
作为常规,了解事物如何影响性能的唯一方法是进行测试。但以下是一些一般性陈述:
“fseek”是否有性能开销?
每个操作都有性能开销,大多数操作只有很小的性能开销。如果您调用“fseek”,并且内核或库已经预读了数据(即读取了比您请求的更多文件),那么它很可能会放弃预读数据,因为它是错误的位置。
例如,“fseek”调用是否实际上要求内核移动磁盘头?
不,它不会。它只是更新内核下次从文件中读取的位置。在您从文件中读取之前,硬盘不会做任何事情。
下一次访问该文件时,磁盘头可能需要移动,也可能不需要移动。但是,无论是否使用“fseek”,它可能仍然需要移动,因为文件可能是分段的,或者因为另一个程序访问了磁盘的其他部分上的不同文件。

它也可以反过来工作。如果您要查找的文件部分恰好在缓存中(因为之前有东西访问过它),内核可以直接从缓存中获取,而无需访问硬盘。

当然,对于SSD、tmpfs等文件,磁头移动是无关紧要的。

此外,fseek的性能成本是否与其“寻找”的距离有关?例如,fseek(1byte)与fseek(100Mb)与fseek(end-of-file)。

可能影响不大。


它只是更新内核下一次从文件中读取的位置。如果fseek()调用的目标位置在与FILE *相关联的已读数据的任何用户空间缓存中,则在读模式下可能甚至不会做到这一点。 - Andrew Henle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接