【发布时间】:2021-02-16 05:36:32
【问题描述】:
要打印文件的内容,可以使用getc:
int ch;
FILE *file = fopen("file.txt", "r");
while ((ch = getc(file)) != EOF) {
// do something
}
getc 函数的效率如何?也就是说,它实际上多久执行一次操作系统调用或需要花费大量时间的事情?例如,假设我有一个 10TB 的文件——调用这个函数数万亿次是不是获取数据的糟糕方法?
【问题讨论】:
-
标准 I/O 缓冲的目的是使一次字符的 I/O 变得可行。除非您采取其他措施(默认情况下,换句话说),否则 I/O 库将读取相当大的数据块(例如 macOS 上的 1 KiB),然后一次分配一个字符有效率的。在现代多线程系统上,每次使用
getc()都会产生一些锁定和解锁开销(名义上至少是这样)——请参阅lockfile(),unlockfile(),trylockfile()。 [...继续...] -
[…continuation…] 如果你的代码是严格的单线程的,你可以使用
getc_unlocked()et al 来避免锁定开销。如果您的代码可以处理更大的块(使用fread()等),则读取从 8 KiB 到 64 KiB 的块可能会带来一些性能优势;您的代码将处理对每个字符的访问。较大的缓冲区大小通常带来的好处可以忽略不计,但您可以衡量一下哪种方法最适合您。 -
getc(),fgetc()有一个由 I/O 系统填充的读取缓冲区。在 Linux 上,大小为8192字节,在 Windows 上为512字节。因此,无论您使用具有 8K 或更少缓冲区的fgets(),还是使用getc(),基本上都是一种清洗。不会有可测量的差异。用于设置低级缓冲区大小的宏已经更改了几次名称,最近的是BUFSIZ。进行更改的提交是 glibc/libio/stdio.h - #define BUFSIZ 8192 -
@David542 — 深夜记忆失效,添加评论后无法检查。抱歉(感谢您指出我的错误)。函数名称实际上以
f开头,因此正确的链接(三个函数一页)是flockfile(),funlockfile(),ftrylockfile()。 (是的,这次我在点击“提交”后检查了 URL。)
标签: c linux performance system-calls