【问题标题】:Why is fseeko() faster with giant files than small ones?为什么 fseeko() 处理大文件比处理小文件更快?
【发布时间】:2010-07-16 17:15:01
【问题描述】:

我在这里得到了一些奇怪的性能结果,我希望 stackoverflow.com 上的人能对此有所了解!

我的目标是一个可以用来测试大搜索是否比小搜索更昂贵的程序...

首先,我通过 dd'ing /dev/zero 创建了两个文件来分隔文件...一个是 1 mb,另一个是 9.8gb...然后我写了这段代码:

#define _LARGE_FILE_API
#define _FILE_OFFSET_BITS 64

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main( int argc, char* argv[] )
{
  struct stat64 fileInfo;
  stat64( argv[1], &fileInfo );

  FILE* inFile = fopen( argv[1], "r" );

  for( int i = 0; i < 1000000; i++ )
    {
      double seekFrac = ((double)(random() % 100)) / ((double)100);

      unsigned long long seekOffset = (unsigned long long)(seekFrac * fileInfo.st_size);

      fseeko( inFile, seekOffset, SEEK_SET );
    }

    fclose( inFile );
}

基本上,这段代码会在整个文件范围内进行一百万次随机搜索。当我在 time 下运行它时,对于 smallfile,我会得到这样的结果:

[developer@stinger ~]# time ./seeker ./smallfile

real    0m1.863s
user    0m0.504s
sys  0m1.358s

当我针对 9.8 gig 文件运行它时,我得到如下结果:

[developer@stinger ~]# time ./seeker ./bigfile

real    0m0.670s
user    0m0.337s
sys  0m0.333s

我对每个文件运行了几十次,结果是一致的。在大文件中查找的速度是在小文件中查找的两倍多。为什么?

【问题讨论】:

  • 您的搜索分布非常稀疏:它们都是文件大小的整数百分比值 (0-99)。尝试将间隔减小到 0.1% 左右,然后是 0.01% 等,看看您是否注意到任何差异。

标签: c performance libc


【解决方案1】:

您测量的不是磁盘性能,而是fseek 设置指针并返回所需的时间。

如果你想测试真正的 IO,我建议你从你正在寻找的位置读取文件。

【讨论】:

  • 哇...好吧,我在寻求读取单个字符之后添加了一个 getc() 调用。现在,在大文件中查找比在小文件中查找稍微贵一点。是否有一些优化可以在下一次 IO 之前对多个后续搜索进行求和并实际完成?哇...
  • a seek() 只是对您计划从下一步读取的操作系统的提示。操作系统具有复杂的调度机制来移动磁盘磁头,从而最大限度地减少所有用户的总行程时间。由于您的读取与其他所有人的读取交错,因此直到最后一刻,操作系统(而不是您的程序,操作系统!)将进行读取是没有意义的。因此,操作系统将您的搜索位置保留在其脑海中,但在实际物理读取数据之前不会对其进行操作。
【解决方案2】:

我认为这与fseeko 的实现有关。

fseek 的手册页表明它只是“为指示的流设置文件位置指示器”。由于设置整数应该与文件大小无关,因此可能有一个“优化”,它将在对小文件而不是大文件进行 fseek 之后执行自动读取(并缓存结果信息)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    相关资源
    最近更新 更多