c - C 中最快的 fgets 实现
问题描述
内部使用了已知的fgets libc 函数实现fgetc()
,如何使用read()
更大的缓冲区或其他方法来加速函数?
例如,我读取/proc/pid/maps
文件以搜索一些字符串。该文件的格式是已知的,目前我使用fgets
链接中的实现read(fd, &c, 1);
而不是getc
. 我认为从文件中读取单个字节比读取 200 个字节要慢。所以我想修改函数以从文件中读取 N 个字节,然后找到一个换行符。我认为替换 1 字节读取可以以某种方式加速该功能。
解决方案
您完全误解了标准 I/O 功能。甚至fgetc
被缓冲。使用 测试实际read
调用的发出strace
。在我的电脑上,阅读/proc/1/maps
:
read(3, "5634f9cf6000-5634f9e44000 r-xp 0"..., 1024) = 1024
read(3, " /lib/x86_64-l"..., 1024) = 1024
read(3, " /lib/x86_64-linux-g"..., 1024) = 1024
read(3, " /lib/x86_64-l"..., 1024) = 1024
read(3, ".0.0\n7feb2b2dc000-7feb2b4db000 -"..., 1024) = 1024
read(3, "0-7feb2b8e7000 r--p 00002000 fd:"..., 1024) = 1024
read(3, "00 rw-p 0001a000 fd:00 145004 "..., 1024) = 1024
read(3, "ux-gnu/liblzma.so.5.2.2\n7feb2c1b"..., 1024) = 1024
read(3, "6_64-linux-gnu/libgcrypt.so.20.2"..., 1024) = 1024
read(3, "000 fd:00 135558 "..., 1024) = 1024
read(3, "--p 0000e000 fd:00 136910 "..., 1024) = 1024
read(3, "001e000 fd:00 131385 "..., 1024) = 1024
read(3, "1.1.0\n7feb2da14000-7feb2da15000 "..., 1024) = 1024
read(3, "0 rw-p 00000000 00:00 0 \n7feb2de"..., 1024) = 1024
read(3, "-237.so\n7feb2e492000-7feb2e69100"..., 1024) = 1024
read(3, " \n7feb2ed15000-7feb2ed36000 rw-p"..., 1024) = 637
read(3, "", 1024) = 0
这些read
调用尝试读取1024
字节,而不仅仅是一个。
该程序是
#include <stdio.h>
int main(void) {
FILE *f = fopen("/proc/1/maps", "r");
while (1) {
char buf[2048];
if (! fgets(buf, 2048, f)) {
break;
}
}
}
如果 1024 字节对您来说还不够,您可以使用setvbuf(3)更改底层缓冲区的大小!
推荐阅读
- c++ - 索引数组时我应该总是使用 size_t 吗?
- python - 将填充的 2-D 图/对象(由 plt.fill 创建)添加到 3-D 图中
- linux - /proc/sys/vm/flush_mmap_pages 去哪儿了?
- angular - 仅将 Wordpress 用作后端 - 处理 WP_SITEURL
- html - 如何使 flexbox 项目等高和/或从同一点开始
- pandas - 用 <、> 和 <= x <= 编写新列
- react-admin - 如何更改 ImageField 中图像的大小?
- acumatica - Acumatica:选择器过滤重复项
- node.js - MONGO_URL 是什么,应该设置什么?
- sql - 使用 WHERE 某一特定列“Select * from table”超时,但其他列可以正常运行