Я видел этот вопрос, и он несколько похож. Я хотел бы знать, действительно ли это большой фактор, который повлияет на производительность моего приложения. Вот мой сценарий.
У меня есть это веб-приложение на Java, которое может загружать тысячи данных из электронной таблицы, которая читается в каждой строке сверху вниз. Я использую System.out.println()
, чтобы показать на стороне сервера, какую строку приложение в данный момент читает.
- Мне известно о создании файла журнала. Фактически, я создаю файл журнала и в то же время показываю журналы в командной строке сервера.
Есть ли другой способ распечатать текущие данные в командной строке?
Java - влияние System.out на производительность
Ответы (6)
Это может повлиять на производительность вашего приложения. Величина будет варьироваться в зависимости от типа оборудования, на котором вы работаете, и нагрузки на хост.
Некоторые моменты, по которым это может повлиять на производительность:
-> Как заявил Rocket Boy, println синхронизирован, что означает, что вы будете нести накладные расходы на блокировку заголовка объекта и можете вызвать узкие места потока в зависимости от вашего дизайна.
-> Для печати на консоли требуется время ядра, время ядра означает, что процессор не будет работать в пользовательском режиме, что в основном означает, что ваш процессор будет занят выполнением кода ядра, а не кода вашего приложения.
-> Если вы уже регистрируете это, это означает дополнительное время ядра для ввода-вывода, а если ваша платформа не поддерживает асинхронный ввод-вывод, это означает, что ваш процессор может зависнуть в ожидании занятости.
Вы действительно можете попробовать и проверить это самостоятельно.
Есть способы избежать этого, например, иметь действительно быстрый ввод-вывод, возможно, огромную машину для специального использования и предвзятую блокировку ваших параметров JVM, если дизайн вашего приложения не будет многопоточным при печати этой консоли.
Как и все, что касается производительности, все зависит от вашего оборудования и приоритетов.
Недавно я тестировал (читал и) писал большие (1-1,5 ГБ) текстовые файлы и обнаружил, что:
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(java.io.FileDescriptor.out), "UTF-8"), 512));
out.println(yourString);
//...
out.flush();
фактически почти на 250% быстрее, чем
System.out.println(yourString);
Моя тестовая программа сначала прочитала около 1 ГБ данных, немного обработала их и выдала в несколько другом формате.
Результаты тестирования (на Macbook Pro, при чтении и записи SSD с использованием одного и того же диска):
- данные-выход-в-систему-выход> output.txt => 1мин32сек
- данные-записанные-в-файл-в-java => 37сек
- данные-записанные-в-буферизованный-писатель-stdout> output.txt => 36сек
Я пытался использовать несколько буферов размером от 256 до 10 КБ, но это не имело значения.
Так что имейте в виду, что если вы создаете инструменты командной строки unix с помощью Java, где вывод должен быть направлен или перенаправлен куда-то еще, не используйте System.out напрямую!
dd
застрял с 512-байтовым буфером по умолчанию (как в этом ответе) из-за спецификации, что делает его привязанным к процессору на современных дисках.
- person that other guy; 09.06.2018
System.out.println()
синхронизируется.
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
Если в него пишут несколько потоков, его производительность пострадает.
Да, это ОГРОМНО повлияет на производительность. Если вам нужно количественное число, то есть много программного обеспечения и / или способов измерения производительности вашего собственного кода.
System.out.println работает очень медленно по сравнению с большинством медленных операций. Это связано с тем, что он требует больше работы на машине, чем другие операции ввода-вывода (и является однопоточным).
Я предлагаю вам записать вывод в файл и tail
вывод этого файла. Таким образом, вывод по-прежнему будет медленным, но не так сильно замедлит работу вашего веб-сервиса.
Вот очень простая программа для проверки производительности System.out.println и сравнения ее с операцией умножения (вы можете использовать другие операции или функции, специфичные для ваших требований).
public class Main{
public static void main(String []args) throws InterruptedException{
long tTime = System.nanoTime();
long a = 123L;
long b = 234L;
long c = a*b;
long uTime = System.nanoTime();
System.out.println("a * b = "+ c +". Time taken for multiplication = "+ (uTime - tTime) + " nano Seconds");
long vTime = System.nanoTime();
System.out.println("Time taken to execute Print statement : "+ (vTime - uTime) + " nano Seconds");
}
}
Производительность зависит от вашей машины и ее текущего состояния.
Вот что у меня получилось: https://www.onlinegdb.com/online_java_compiler
a * b = 28782. Time taken for multiplication = 330 nano Seconds
Time taken to execute Print statement : 338650 nano Seconds