c - C 中最快的 fgets 实现

标签 c performance implementation fgets libc

已知fgets libc函数实现内部使用了fgetc(),我如何使用具有更大缓冲区或其他方法的read()来加速函数?

例如,我读取 /proc/pid/maps 文件来搜索一些字符串。文件的格式已知,目前我在链接中使用 fgets 实现与 read(fd, &c, 1); 而不是 getc。我认为从文件中读取单个字节比读取 200 个字节慢。所以我想修改函数以从文件中读取N个字节,然后找到换行符。我认为替换 1 字节读取可以以某种方式加速该功能。

最佳答案

您完全误解了标准 I/O 函数。甚至fgetc 也会被缓冲。使用 strace 测试实际 read 调用的发出。在我的计算机上,读取 /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 - C 中最快的 fgets 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51221322/

相关文章:

c - 选择小于架构大小的变量是一个有效的选择吗?

oracle - 有人能解释一下 MERGE 语句在 Oracle 中的真正作用吗?

Java - Spring数据访问对象实现

c - 如何在 C 中正确链接 winsock2.h?

C: 如何知道当前输入是否有\b

c - 如果 C 中的循环未正确迭代

asp.net-mvc - 渲染 View 时 ASP.NET MVC 4 很慢

sql - 子查询不在性能问题中

html - 动态内容的 css 文件中的数据 URI

keras - 如何在训练期间更改批量大小?