我一直认为多次调用putc比使用puts或printf更快。要打印“hello”,例如,在实际程序中我总是使用puts或printf,但现在我正在编写一个生成C代码的程序,所以我想知道是否生成代码为putchar('h'); putchar('e') ...
因为我是第一个认为它应该更快。但我进行了一项测试,结果非常有趣。编译器是GCC。
#include <stdio.h>
#include <time.h>
int main() {
time_t timer;
FILE *f;
int i;
f = fopen("out.txt", "w");
#define START_TIMER(TIMER) TIMER = clock()
#define ELAPSED_TIME(TIMER)\
(double)(clock() - TIMER) / (double)CLOCKS_PER_SEC
enum { NUM_ITERS = 9999999 };
START_TIMER(timer);
for (i = 0; i < NUM_ITERS; i++) {
putc('h', f);
putc('e', f);
putc('l', f);
putc('l', f);
putc('o', f);
putc('\n', f);
}
printf("%.3f\n", ELAPSED_TIME(timer));
START_TIMER(timer);
for (i = 0; i < NUM_ITERS; i++) {
fputs("hello", f);
}
printf("%.3f\n", ELAPSED_TIME(timer));
START_TIMER(timer);
for (i = 0; i < NUM_ITERS; i++) {
fprintf(f, "hello\n");
}
printf("%.3f\n", ELAPSED_TIME(timer));
return 0;
}
没有优化的结果:
4.247 1.013 1.195
优化结果(-O2):
0.910 1.184 1.315
优化结果(-O3):
0.920 1.158 1.311
因此,在没有优化的情况下天真地执行时,多次调用putc比使用printf的put更慢。首先,我很好奇为什么会这样。其次,我应该采用哪种方式生成程序生成的C代码?
答案 0 :(得分:5)
你对什么应该更快的直觉是错误的。通常,putc
/ putchar
每个字节写入的开销很大,因为有一个完整的函数调用循环,stdio流(stdout
)的潜在锁定被定位,每个字节等。另一方面,printf
或puts
等函数每次调用的开销比putc
更多(例如printf
必须处理格式字符串,并且puts
必须调用strlen
或等价物),但无论您编写多少字节,该开销只会发生一次。实际写入可以作为批量复制发送到FILE
的缓冲区,也可以批量写入基础文件(如果FILE
未缓冲)。
至于优化级别如何影响这一点,-O0
可能会在进行函数调用时产生更多的开销,并在更高的优化级别进行优化。