putc和putchar的表现?

时间:2014-10-06 22:28:02

标签: c printf putchar

我一直认为多次调用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代码?

1 个答案:

答案 0 :(得分:5)

你对什么应该更快的直觉是错误的。通常,putc / putchar每个字节写入的开销很大,因为有一个完整的函数调用循环,stdio流(stdout)的潜在锁定被定位,每个字节等。另一方面,printfputs等函数每次调用的开销putc更多(例如printf必须处理格式字符串,并且puts必须调用strlen或等价物),但无论您编写多少字节,该开销只会发生一次。实际写入可以作为批量复制发送到FILE的缓冲区,也可以批量写入基础文件(如果FILE未缓冲)。

至于优化级别如何影响这一点,-O0可能会在进行函数调用时产生更多的开销,并在更高的优化级别进行优化。