在C中快速打印出大量的整数

时间:2013-12-10 20:37:38

标签: c performance output

我必须打印1,000,000个四位数字。我为此目的使用了printf

 for(i=0;i<1000000;i++)
 { 
     printf("%d\n", students[i]);
 }

结果太慢了。有一种更快的方法可以打印出来。

2 个答案:

答案 0 :(得分:2)

您可以创建一个数组,用输出数据填充它,然后立即打印出该数组。或者如果存在内存问题,只需将该数组拆分为较小的块并逐个打印即可。

答案 1 :(得分:1)

这是我尝试使用简单的特例代码替换printf和stdio流缓冲:

int print_numbers(const char *filename, const unsigned int *input, size_t len) {
    enum {
        // Maximum digits per number. The input numbers must not be greater
        // than this!
#       if 1
        DIGITS = 4,
#       else
        // Alternative safe upper bound on the digits per integer
        // (log10(2) < 28/93)
        DIGITS = sizeof *input * CHAR_BIT * 28UL + 92 / 93,
#       endif
        // Maximum lines to be held in the buffer. Tune this to your system,
        // though something on the order of 32 kB should be reasonable
        LINES = 5000
    };

    // Write the output in binary to avoid extra processing by the CRT. If necessary
    // add the expected "\r\n" line endings or whatever else is required for the
    // platform manually.
    FILE *file = fopen(filename, "wb");
    if(!file)
        return EOF;

    // Disable automatic file buffering in favor of our own
    setbuf(file, NULL);

    while(len) {
        // Set up a write pointer for a buffer going back-to-front. This
        // simplifies the reverse order of digit extraction
        char buffer[(DIGITS + 1 /* for the newline */) * LINES];
        char *tail = &buffer[sizeof buffer];
        char *head = tail;
        // Grab the largest set of lines still remaining to be printed which
        // will safely fit in our buffer
        size_t chunk = len > LINES ? LINES : len;
        const unsigned int *input_chunk;
        len -= chunk;
        input += chunk;
        input_chunk = input;

        do {
            // Convert the each number by extracting least-significant digits
            // until all have been printed.
            unsigned int number = *--input_chunk;
            *--head = '\n';
            do {
#               if 1
                char digit = '0' + number % 10;
                number /= 10;
#               else
                // Alternative in case the compiler is unable to merge the
                // division/modulo and perform reciprocal multiplication
                char digit = '0' + number;
                number = number * 0xCCCDUL >> 19;
                digit -= number * 10;
#               endif
                *--head = digit;
            } while(number);
        } while(--chunk);

        // Dump everything written to the present buffer
        fwrite(head, tail - head, 1, file);
    }

    return fclose(file);
}

我担心这不会比你原来的相当小的常数因素(通过避免一些printf格式解析,每字符缓冲,区域设置处理,多线程锁定等)给你买得多。

除此之外,您可能需要考虑处理输入并即时写入输出,而不是将读取/处理/写入作为单独的阶段。当然这是否可行完全取决于要执行的操作。

哦,不要忘记在构建应用程序时启用编译器优化。使用分析器进行操作也不会有任何损害。