标准输出缓冲区的大小是多少?

9 浏览
0 Comments

标准输出缓冲区的大小是多少?

我正在向标准输出写入大量数据,并且观察到根据输出控制台的显示,程序的执行时间是变化的。例如,在NetBeans控制台上,程序比在Windows命令提示符中慢。\n因此,我认为写入stdout会填充一个缓冲区,并且当该缓冲区已满时,写入操作会变为阻塞(因为控制台输出无法快速消耗)。\n我用一个Java程序重现了这种行为。\n下面是一个输出数据的程序。\n

public class Output {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10_000; i++) {
            System.out.println("Awesone Output ");
        }
        System.out.println("Total time : " + (System.currentTimeMillis() - start));
    }
}

\n下面是一个从上述程序中消耗数据的程序\n

public class StdoutBlocking {
    public static void main(String[] args) throws IOException, InterruptedException {
        ProcessBuilder processBuilder = new ProcessBuilder("java", "stackoverflowDemo.StdoutBlocking.Output");
        processBuilder.directory(new File("C:/Users/me/Documents/NetBeansProjects/tmp/build/classes"));
        Process process = processBuilder.start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = null;
        String lastLine = null;
        while ((line = reader.readLine()) != null) {
            Thread.sleep(10);
            lastLine = line;
        }
        System.out.println("done : " + lastLine);
    }
}

\n我启动第二个程序来启动输出并消耗其输出。\n如果没有sleep,Output程序会非常快,但它非常慢。\n那么这个缓冲区的大小是多少?\n这只是出于我的好奇心,我并不打算实现什么特别的目标。

0
0 Comments

标准输出缓冲区大小是多少?

在这段内容中,提到了程序的速度与缓冲区大小无关。程序在输出每一行时都会至少休眠10毫秒(共10000行)。因此,使用Thread.sleep(10)时,程序至少会停顿100秒。这就是为什么使用Thread.sleep()时程序会变慢。

关于System.out.println()的性能,请查看这个问题:为什么System.out.println()如此慢?

底层的操作系统操作(在控制台窗口上显示字符)很慢,原因如下:

1. 字节必须发送到控制台应用程序(应该很快)

2. 每个字符必须使用(通常)TrueType字体呈现(这很慢,关闭抗锯齿可能会提高性能)

3. 显示区域可能需要滚动以将新行附加到可见区域(最好的情况是位块传输操作,最糟糕的情况是重新呈现整个文本区域)

还可以在Process类的Javadoc中找到关于此的说明:

由于某些本机平台只为标准输入和输出流提供了有限的缓冲区大小,如果不能及时写入子进程的输入流或读取子进程的输出流,可能会导致子进程阻塞甚至死锁。

对于UNIX系统,您可以查看此链接:https://unix.stackexchange.com/questions/11946/how-big-is-the-pipe-buffer

在我的例子中,明显有两个程序,我在谈论的是第一个程序的速度,它没有休眠!第一个程序只是因为第二个程序读取stdout太慢而变慢。第二个程序是模拟控制台的。这与呈现无关,因为在我的测试中屏幕上几乎没有打印任何东西。

要检查是否由于打印到屏幕而导致的速度变慢,可以将System.out.println()替换为在文件系统上打印到文件的方式。

我没有在任何地方打印“awesome output”,我只是从第二个程序中读取它。如果我慢慢读取它,第一个程序就会变慢;如果我快速读取它,它就会变快。我想知道为什么?我不是在尝试优化任何东西,我只是想知道为什么消费速度会影响生产速度。这两个进程是独立的,唯一共同的东西应该是操作系统管理的缓冲区,我正在寻找相关信息。你真的理解这个现象吗?

0
0 Comments

标准输出缓冲区的大小是多少?

标准输出缓冲区的默认大小是8192。你可以通过查看System.outSystem.err的源代码中的方法(如println(String))来看到这一点。它们使用默认缓冲区大小的BufferedWriter

我认为你没有看到正确的缓冲区。我认为这是一个操作系统的设置,我的第一个程序可能是C、Python、Bash或其他任何语言。我不太确定,如果有人能确认一下就好了。

0