У меня есть простая автономная Java-программа, которая выводит некоторые данные на консоль с помощью System.out.println/printf
.
Программе требуется около 3 секунды , чтобы прочитать ее ввод и записать вывод в консоль . Выходные данные содержат около 1000 строк по 200 символов в каждой, что в сумме составляет около 200 кБ.
Если я запускаю его с перенаправлением stdout в файл , то это займет в течение 2 минут для завершения.
ОС - RedHat Linux, оболочка - bash. Минимальный пример, который показывает тот же эффект:
public class WriteToStdout { // write ~100K to stdout
public static void main( String[] args ) {
for ( int i = 0; i < 100; i++ ) {
System.out.printf( "%1000d\n", 1234 );
}
}
Беги так:
/home/gsl> time java WriteToStdout
... console output omitted ...
real 0m0.163s
user 0m0.147s
sys 0m0.032s
/home/gsl> time java WriteToStdout > file
real 0m1.045s
user 0m0.151s
sys 0m0.036s
Диск, показанный ниже, работает быстро: если я копирую файлы или выполняю yes > file
, он записывает около 100 МБ в секунду, как и ожидалось.
Если я перенаправлю через cat
, то снова быстро :
/home/gsl> time java WriteToStdout | cat > file
real 0m0.152s
user 0m0.146s
sys 0m0.029s
Все одиночные тесты повторялись много раз и показывают одинаковое время при каждом запуске.
Так что же делает JVM, когда видит, что я перенаправляю в файл?