为什么写入现有文件比写入不存在的文件要慢?

时间:2014-11-29 15:27:57

标签: c performance io fwrite

请考虑以下示例代码:

/* verify.c */
#include <stdio.h>

int
main (int argc, char *argv[])
{
  if (argc < 2)
    return 0;

  char *filename = argv[1];

  FILE *f = fopen(filename, "w");
  if (!f)
    perror("something went wrong");

  // random data
  #define SIZE 65536
  #define ITER 1024
  unsigned int buffer[SIZE] = { 0 };

  unsigned int i;
  for (i = 0; i < ITER; ++i)
    {
      int res = fwrite(buffer, sizeof(*buffer), SIZE, f);
      if (res != SIZE)
        perror("something went wrong");
    }

  fclose(f);

  return 0;
}

不感兴趣,他的程序会将 random 数据写入文件。 有趣的是,如果文件不存在,程序的速度要快几个数量级,尽管它的内容与程序完全无关。

time ./verify notexists

  real    0m0.162s
  user    0m0.000s
  sys     0m0.162s

time ./verify exists

  real    0m3.807s
  user    0m0.002s
  sys     0m0.268s

为什么?

编辑: 感谢@ rodrigo的建议,我通过strace运行了两个案例,并报告如果文件存在,close系统调用需要很长时间才能完成。

如果文件存在:

close(3)                                = 0 <2.673454>

否则:

close(3)                                = 0 <0.000011>

1 个答案:

答案 0 :(得分:1)

当文件存在时,"w"将截断它,即删除其所有内容。这需要时间,可能很多时间是文件非常大,文件系统不是很好(FAT?)。

与此相反,当文件不存在时,将创建它,即添加目录条目和inode或文件系统使用的任何内容。但这些结构总是很小,所以这不是什么大问题。