要打印文件的内容,可以使用getc
int ch;
FILE *file = fopen("file.txt", "r");
while ((ch = getc(file)) != EOF) {
// do something
}getc函数的效率如何?也就是说,它到底多久进行一次操作系统调用,或者需要花费相当长的时间?例如,假设我有一个10 to文件--调用这个函数数万亿次会不会是获取数据的糟糕方法?
发布于 2021-02-16 05:46:20
也就是说,它到底多久进行一次操作系统调用,或者需要花费相当长的时间?
您可以查看GNU libc或musl-libc的源代码来研究getc的实现。您还应该学习“禁止酷刑公约”(1)和wc(1)的实现。两者都是开源。GNU as (GNU二进制的一部分)是一个自由软件 (由GCC在大多数编译中内部使用),它在实践中运行非常快,并进行文本操作(将汇编程序文本输入转换为二进制对象文件)。,您可以从它的源代码中获得灵感。
您可以使用setvbuf(3)更改缓冲区大小。
您可能需要使用fread(3)或fgets(3)一次读取几个字节,可能是按几千字节的数据块读取。
您还可以使用调试器gdb(1)或斯特拉斯(1)实用程序来确定何时使用系统(2)以及哪些使用系统(2)。
例如,假设我有一个10 to文件--调用这个函数数万亿次会不会是获取数据的糟糕方法?
很可能不是,因为内核的页缓存。
您应该对您的程序进行概要分析和基准测试,以找出其瓶颈。
大多数情况下,它不会是getc。请参阅时间(7)和gprof(1) (并使用作为gcc -O3 -pg -Wall调用的GCC编译所有代码)
如果原始输入性能在您的程序中是关键的,请考虑直接和明智地使用开放(2)、读(2)、mmap(2)、madvise(2)、readahead(2)、财务咨询(2)、关闭(2)。这些系统中的大多数都可能会失败,参见errno(3)。
您还可以更改您的文件系统(例如,从Ext4到XFS,请参阅ext4(5)和xfs(5)),购买更好的SSD磁盘或更多物理内存,或者使用山(2)选项来提高性能。
还请参见/proc伪文件系统(so proc(5).);和这答案。
您可能希望使用像方石岩或PostGreSQL这样的数据库。
您的程序可以在运行时生成C代码(就像manydl.c做的那样),可以尝试各种方法(使用gcc -O3 -fPIC /tmp/generated-c-1234.c -shared -o /tmp/generated-plugin-1234.so将生成的C代码/tmp/generated-c-1234.c编译为插件,然后是< code >D53生成的插件的dlopen(3)-ing和dlsym(3)-ing ),以及E 154使用E 255 机器学习 E 157/code>技术,以找到一个非常好的E 258(针对当前硬件和计算机)。它还可以更直接地使用阿斯吉特或利布生成机器代码,尝试几种方法,并根据特定情况选择最佳的方法。Pitrat的书“https://rads.stackoverflow.com/amzn/click/com/1848211015和blog”(仍然是这里)更详细地解释了这种方法。概念框架称为 https://en.wikipedia.org/wiki/Partial_evaluation。另见这。
您还可以使用现有的解析器生成器,如野牛或反。他们正在生成C代码。
Ian的libbacktrace跟踪在这种动态元编程方法中也很有用(生成各种形式的C代码,并根据使用dladdr(3)检查的调用堆栈选择最佳的C代码)。
在尝试任何实验之前,会与您的经理/老板/客户讨论花费几个月的全职工作来获得几%的性能的机会。考虑到通过升级硬件可以获得相同的增益。
如果您的百万字节输入文本文件不经常更改(例如,每周给出,例如在生物信息学软件中),则可能值得对其进行预处理并将其转换为-in批处理模式--转换为二进制文件、某个方石岩数据库、某个GDBM索引文件或一些雷迪斯文件。然后,记录二进制文件或数据库的格式(使用EBNF表示法,从精灵(5)获得灵感)是非常重要的。
https://stackoverflow.com/questions/66219179
复制相似问题