Каков размер стандартного размера выходного буфера? - PullRequest
0 голосов
/ 03 июля 2018

Я записываю много данных в вывод stdandard и замечаю, что в зависимости от консоли вывода время выполнения программы является переменным. Программа работает медленнее в консоли NetBeans, чем в Windows cmd, например.

Так что я думаю, что запись в stdout заполняет буфер, и запись становится блокированной, когда этот буфер заполнен (вывод на консоль работает недостаточно быстро).

Я воспроизводлю это поведение с помощью программы на Java.

Здесь программа, которая выводит данные.

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));
    }

}

А вот и программа, которая потребляет данные из вышеуказанной программы

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);

    }
}

Я запускаю второй, который запускает вывод и потребляет его вывод. Без сна программа вывода работает очень быстро и очень медленно.

Так, каков размер этого буфера ??

Это только для моего Любопытства, я не пытаюсь достичь Нечто особенного

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Without sleep the program is really quick with it's very slow. это не имеет отношения к размеру буфера. Ваша программа спит не менее 10 миллисекунд для каждой линии вывода (10000 строк). Так что с Thread.sleep(10) ваша программа ничего не делает в течение как минимум 100 секунд. Вот почему это медленно с Thread.sleep().

Что касается производительности System.out.println(), проверьте этот вопрос: Почему System.out.println такой медленный?

Операция базовой операционной системы (отображение символов в окне консоли) выполняется медленно, поскольку

1.Байты должны быть отправлены в консольное приложение (должно быть достаточно быстрым)

2.Каждый символ должен отображаться с использованием (обычно) шрифта истинного типа (это довольно медленно, отключение сглаживания может повысить производительность, кстати)

3. Возможно, потребуется прокрутить отображаемую область, чтобы добавить новую строку в видимую область (лучший случай: операция передачи битового блока, наихудший случай: повторное отображение всей текстовой области)

Также вы можете найти это в Javadoc для Process class

Поскольку некоторые собственные платформы предоставляют ограниченный размер буфера только для стандартных входных и выходных потоков, невозможность оперативной записи входного потока или чтения выходного потока подпроцесса может привести к блокировке подпроцесса и даже к тупиковой ситуации.

Для UNIX вы можете проверить эту ссылку: https://unix.stackexchange.com/questions/11946/how-big-is-the-pipe-buffer

0 голосов
/ 03 июля 2018

Размер буфера по умолчанию для System.out и System.err равен 8192. Вы можете увидеть его, посмотрев исходный код его методов, таких как println(String). Они используют BufferedWriter с размером буфера по умолчанию.

...