为什么fgetc太慢了?

我编写了一个程序,通过fgetc读取整个文件:

 while ((c = fgetc(f)) != EOF) { ... } 

但该计划太慢了。 当我把fgetc变成fread

 static unsigned char buf[4096]; while ((n = fread(buf, 1, sizeof(buf), f)) > 0) { ... } 

该程序的工作速度提高了约10倍

为什么? 据我所知, fgetc是一个缓冲函数,因此它应该像第二个版本一样快速地使用显式缓冲区,不是吗?

你住在商店附近。 你需要得到100jar汤。 哪个更有效率,100次到商店获得1次可以每次或1次到商店获得100jar? 显然是1次旅行,因为每次旅行都有花费时间的开销。

在fgetc的情况下,存在各种开销。

  • 函数调用
  • 文件是否打开?
  • 在文件结束?
  • 缓冲区是空的吗?
  • 锁定
  • 等等

这些东西可以为所有的汤做一次,或者每次可以做一次。 单独地,每个开销都很小,但是当重复多次时,总和变得很重要。

使用fgetc,您不仅可以获得更多的函数调用(每个函数都有其开销),但fgetc也可以在multithreading应用程序中获取锁定(这是由POSIX强制实施的)。