是否应将stdout和stdin设置为在C中不缓冲? [英] Should I set stdout and stdin to be unbuffered in C?

查看:229
本文介绍了是否应将stdout和stdin设置为在C中不缓冲?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于 stdin stdout 有时会缓冲 printf scanf getchar 未执行。我通常使用 fflush(stdout)刷新输出缓冲区,但是代码可能因此变得非常不可读。如果我使用 setbuf(stdin,NULL) stdin stdout 设置为无缓冲$ c>和 setbuf(stdout,NULL)我会让程序性能更好还是更差?

Because of stdin and stdout buffering sometimes printf, scanf and getchar are not executed. I usually flush output buffer using fflush(stdout) but code can become very unreadable because of that. If I set stdin and stdout unbuffered using setbuf(stdin, NULL) and setbuf(stdout, NULL) will I make my program perform better or worse?

推荐答案

完全不缓冲地制作 stdin stdout 会使程序在处理较大内容时性能变差文件输入/输出的数量。大多数I / O请求将按系统逐字节分解为系统调用。

Making stdin or stdout completely unbuffered can make your program perform worse if it handles large quantities of input / output from and to files. Most I/O requests will be broken down as system calls on a byte by byte basis.

请注意,缓冲不会导致 printf scanf getchar 不执行: printf 输出到最终目标的时间可能会延迟,因此通过 scanf getchar 进行的输入操作可能不会

Note that buffering does not cause printf, scanf and getchar to not be executed: printf output to the final destination can just be delayed, so the input operation via scanf or getchar may occur without a prompt.

还要注意,将输入设置为未缓冲可能在终端上无效,因为终端本身执行自己的缓冲,该缓冲通过 stty ioctl

Note also that setting intput as unbuffered may not be effective from the terminal because the terminal itself performs its own buffering controlled via stty or ioctl.

大多数C库都有一个导致 stdin 读取时要刷新的> stdout 需要从系统获取数据,但是C标准中未指定此行为,因此某些库不要实现它。在输入操作之前和进度表等临时消息之后,将调用添加到 fflush(stdout); 是安全的。对于大多数目的,最好让C启动根据与 stdin stdout <相关的系统句柄的类型来确定适当的缓冲策略。 / code>流。常见的默认设置是对设备进行行缓冲,对文件进行完全缓冲,其大小为 BUFSIZ

Most C libraries have a hack that causes stdout to be flushed when reading from stdin requires getting data from the system, but this behavior is not specified in the C Standard, so some libraries do not implement it. It is safe to add calls to fflush(stdout); before input operations, and after transitory messages such as progress meters. For most purposes, it is best to let the C startup determine the appropriate buffering strategy depending upon the type of system handle associated with the stdin and stdout streams. The common default is line buffered for devices and fully buffered with a size of BUFSIZ for files.

要想知道潜在的性能影响,请编译以下简单的 ccat 程序:

To get an idea of the potential performance hit, compile this naive ccat program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    int c, size;

    if (argc > 1) {
        if (!strcmp(argv[1], "BUFSIZ"))
            size = BUFSIZ;
        else
            size = strtol(argv[1], NULL, 0);

        if (size == 0) {
            /* make stdin and stdout unbuffered */
            setvbuf(stdin, NULL, _IONBF, 0);
            setvbuf(stdout, NULL, _IONBF, 0);
        } else
        if (size > 0) {
            /* make stdin and stdout fully buffered */
            setvbuf(stdin, NULL, _IOFBF, size);
            setvbuf(stdout, NULL, _IOFBF, size);
        } else {
            /* make stdin and stdout line buffered */
            setvbuf(stdin, NULL, _IOLBF, -size);
            setvbuf(stdout, NULL, _IOLBF, -size);
        }
    }
    while ((c = getchar()) != EOF) {
        putchar(c);
    }
    return 0;
}

时间程序执行多次复制大文件,以最大程度地减少文件缓存的副作用。

Time program execution copying a large file several times to minimize file caching side effects.

在Debian linux上,我得到了3.8MB文本文件的计时:

On a Debian linux box I get these timings for a 3.8MB text file:

chqrlie@linux:~/dev/stackoverflow$ time wc w
 396684  396684 3755392 w
real    0m0.072s
user    0m0.068s
sys     0m0.000s

chqrlie@linux:~/dev/stackoverflow$ time cat < w > ww
real    0m0.008s
user    0m0.000s
sys     0m0.004s

chqrlie@linux:~/dev/stackoverflow$ time ./ccat < w > ww
real    0m0.060s
user    0m0.056s
sys     0m0.000s

chqrlie@linux:~/dev/stackoverflow$ time ./ccat 0x100000 < w > ww
real    0m0.060s
user    0m0.058s
sys     0m0.000s

chqrlie@linux:~/dev/stackoverflow$ time ./ccat 0 < w > ww
real    0m5.326s
user    0m0.632s
sys     0m4.684s

chqrlie@linux:~/dev/stackoverflow$ time ./ccat -0x1000 < w > ww
real    0m0.533s
user    0m0.104s
sys     0m0.428s

如您所见:


  • 设置 stdin stdout 到未缓冲会导致程序减慢几乎 100 的速度,

  • 使用行缓冲会使速度减慢 10 的因数(因为行很短,平均9到10个字节)

  • 使用较大的缓冲区不会显示任何改善,时序差异不会

  • 天真的实现速度非常快,但是真正的 cat 实用工具针对 6 使用了更快的API

  • setting stdin and stdout to unbuffered causes the program to slow down by a factor of almost 100,
  • using line buffering slows down by a factor of 10 (because lines are short, 9 to 10 bytes on average)
  • using a larger buffer does not show any improvement, the timing difference is not significant,
  • the naive implementation is quite fast, but the real cat utility uses faster APIs for 6 times faster execution times.

结论:请勿设置 stdin stdout 设置为无缓冲,即使对于中等大小的文件,也会显着影响性能。

As a conclusion: do not set stdin and stdout to unbuffered, it will impact performance significantly for even moderately large files.

这篇关于是否应将stdout和stdin设置为在C中不缓冲?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆