|
|
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Всем хороших выходных! Решил на досуге изучить вопрос влияния логгирования на производительность. Имею простой пустой цикл.. Код: java 1. 2. ... и хочу максимально подробно логгировать переменную i, с минимальным импактом на производительность. 1) просто вставить system.out.println() в цикл. замедляет очень сильно. 2) создать надзирающий daemon поток который печатает эту переменную, она должна быть volatile как по учебнику, замедляет прилично. 3) то же, но переменная без volatile. Ухудшение раз в 10 меньше чем в п.2. Оно почти не связано с потоком, а связано что переменная теперь не локальная. Что я узнать-то хотел. 1) Какой оптимальный алгоритм для реализации этой задачи? Лучше все-таки логгировать из основного потока, или из наблюдающего потока? Предполагаю, библиотеки логгирования решают эту задачу, или есть смысл делать как я? 2) Оказалось, что запись в статическую переменную класса относительно записи в локальную переменную замедляет данный код раз в тыщу. Где бы почитать про Джаву на таком уровне? Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.11.2015, 21:42 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
вынести условие Код: java 1. в основной цикл ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2015, 00:31 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2015, 10:59 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
условие i % 100000000 не совместимо с "максимально подробно логгировать" Кроме того, такое логгирование, когда другой поток "смотрит" в сырые данные - это вообще как правило, не есть правильно. Так можно логгировать искусственную задачу, в реальном проекте это скорей всего будет плохо. Принцип может быть такой. Данные логов кладутся в очередь в том же потоке, а потом (через время или по достижении порогового размера) другой поток их забирает и пишет в лог. при этом, до некоторой величины граничного потока данных, оно тормозить не будет - пока старая порция будет успевать залоггироваться. Когда поток данных превысит эту величину, то все начнет тормозить - но это уже будет подход к границе производительности. насчет волатильных переменных, скоростей записи, чтения, публикации в др потоки - смотрите на ютуб ранние видео с канала JUGRuVideo, а так же поиском пробивайте имена людей, которые эти доклады делают. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2015, 14:21 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
забавно. следующий код у меня отрабатывает примерно за 13 миллисекунд. но если заменить Код: plaintext Код: plaintext Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 01:30 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Dymytry1) просто вставить system.out.println() в цикл. замедляет очень сильно. System.out.println() может выводить в GUI, текстовую консоль, в файл или вообще вникуда. Производительность каждого варианта разная. Dymytry2) создать надзирающий daemon поток который печатает эту переменную, она должна быть volatile как по учебнику, замедляет прилично. При чем тут учебник? volatile решает определенную задачу, но для вашей существуют и другие решения, просто вы о них ещё не знаете. Начните хотя бы с ExecutorService Dymytry3) то же, но переменная без volatile. Ухудшение раз в 10 меньше чем в п.2. Оно почти не связано с потоком, а связано что переменная теперь не локальная. Понятно что ничего не понятно. Dymytry1) Какой оптимальный алгоритм для реализации этой задачи? На сколько я знаю, очереди с буферизированой записью в файл. Логируемое сообщение создаётся в рабочем потоке, никаких volatile для этого не нужно. Сообщение складывается в очередь. Фоновый поток логгера выгребает сообщения и пачкой пишет их в файл. DymytryЛучше все-таки логгировать из основного потока, или из наблюдающего потока? Почему именно "наблюдающего"? Других вариантов нет? DymytryПредполагаю, библиотеки логгирования решают эту задачу, или есть смысл делать как я? Смысла делать как вы нет. Даже самый древний log4j спокойно пишет сотни мегабайт логов в течении максимум пары секунд (в зависимости от устройства IO) Dymytry2) Оказалось, что запись в статическую переменную класса относительно записи в локальную переменную замедляет данный код раз в тыщу. Где бы почитать про Джаву на таком уровне? Ключевые слова для Google JIT, microbenchmarking, JMH, client JVM, server JVM ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 09:27 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
DymytryРешил на досуге изучить вопрос влияния логгирования на производительность. Имею простой пустой цикл.. for (i = 0; i<Integer.MAX_VALUE; i++) { } ... и хочу максимально подробно логгировать переменную i, с минимальным импактом на производительность. Лучше на досуге поизучайте русский язык. Ваше изучение импакта не имеет смысла (нот хавает нифига тхе сенсе), поскольку пример не имеет отношения к реальным задачам. Если они у вас есть, то изучайте на них. Но в общем можно сказать, что и в крупных программах это обычно не проблема, однако есть средства предотвращения излишней нагрузки от логирования, их и надо изучить. А именно: 1) Разделить сообщения на уровни. В настройках логирования (лучше в отдельном файле, а не в и исходном коде программы) для обычной эксплуатации указать более высокий уровень (меньше сообщений), а при обнаружении ошибок сменить его на менее высокий. в популярной библиотеке log4j надо использовать как минимум 2 уровня - ERROR и DEBUG. В других посмотреть, какие там есть уровни. 2) Задать, чтобы команды логирования срабатывали только при достаточном уровне. Например, в log4j (или LogBack) это будет выглядеть как: Код: java 1. 2. 3. Эта предосторжность может иметь смысл, если для создания сообщения требуется существенная работа. 3) Вместо log4j (самая популярная библиотека) по возможности использовать LogBack (автор log4j и LogBack утверждает, что LogBack быстрее. Я не проверял). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 13:42 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Partisan Mпоскольку пример не имеет отношения к реальным задачам. Если они у вас есть, то изучайте на них +1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 13:56 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
DymytryВсем хороших выходных! ... и хочу максимально подробно логгировать переменную i, с минимальным импактом на производительность. 1) просто вставить system.out.println() в цикл. замедляет очень сильно. 2) создать надзирающий daemon поток который печатает эту переменную, она должна быть volatile как по учебнику, замедляет прилично. 3) то же, но переменная без volatile. Ухудшение раз в 10 меньше чем в п.2. Оно почти не связано с потоком, а связано что переменная теперь не локальная. Что я узнать-то хотел. 1) Какой оптимальный алгоритм для реализации этой задачи? Лучше все-таки логгировать из основного потока, или из наблюдающего потока? Предполагаю, библиотеки логгирования решают эту задачу, или есть смысл делать как я? 2) Оказалось, что запись в статическую переменную класса относительно записи в локальную переменную замедляет данный код раз в тыщу. Где бы почитать про Джаву на таком уровне? Оптимизацию логгирования я-бы начал со следующего. 1) Выбор библиотеки логгирования. Что есть? Тут сравнение по перформансу. Log4j, LogBack, Log4j2 https://logging.apache.org/log4j/2.x/performance.html Обрати внимание на "Asynchronous Logging Performance Improvements". Можно также посмотреть какие стоят Appenders. Файловые - достаточно быстры. Но JDBCAppender, SNMPAppender, и пищущие в сислог операционки будут скорее всего буферизироваться а по заполнении буфера тормозить и блокировать нормальный flow алгоритма. 2) Пересмотреть смысл самой задачи. Если ты борешся с проблемой то ее надо "вычленить". Незачем логгировать простыню трафика типа "entry-exit" в каждый codeblock, callback, или сеттер. Что потом делать с такой аналиткой? Не хватит никаких терабайтов чтобы это хранить. Имеет смысл сделать логгирование избирательным. Логгировать СОБЫТИЕ. Например Код: java 1. 3) Убрать строковые операции и лишнее форматирование. В старых библиотеках. Мы делали конкатенацию Код: java 1. И чтобы отсекать конкатенацию для level > fine от более строгих нужно было оборачивать вызов логгирования проверкой условия. В новых библиотеках есть гарантия того что строковая операция и форматирование не будет работать для "отсекаемых" уровней если мы используем специальный синтаксис с multiple arguments и bracers. Код: java 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 15:20 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Test.java Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. log4.xml Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. Сотня итераций, вывод на экран (FATAL), в файл и nullAppender (TRACE): Код: plaintext 1. 2. Всё тоже самое, кроме уровня (везде FATAL): Код: plaintext 1. 2. P.S. AsyncLogger настраивается только через xml-конфигурацию. Создаётся (перезаписывается) файл Test.log в текущем каталоге. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 18:35 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Лучше так (без предупреждений об устаревшем API): Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. Ну и замеры времени более "честные" - исключены (фиксированные) затраты времени на создание конфигурации и получение логгеров. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 19:19 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Ну и совсем косметика: Test.java Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 19:24 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
rfq, О да, всё придумано до нас. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 19:30 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Консоль штука медленная, поэтому запускать лучше так (windows): Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 19:35 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Dymytryс минимальным импактомс чем? о_О ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2015, 22:57 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Более содержательный пример Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. Код: plaintext 1. 2. 3. 4. 5. Если я нигде не накосячил (судя по файловому логу - не накосячил), то, в нулевом приближении, AsycnLogger - вполне эффективен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2015, 17:47 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Всем большое спасибо! Пойду изучать исходники библиотек логгирования. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2015, 21:56 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
IMHO логгирование показывает весь блеск и нищету кофе-машины. С одной стороны JIT. Казалось бы сделай макросы условную компиляции управляемые из Runtime. И при их изменении инвалидируй скомпилированный код использовавший их и компилируй заново. Ан нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 14:20 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Сергей АрсеньевIMHO логгирование показывает весь блеск и нищету кофе-машины. С одной стороны JIT. Казалось бы сделай макросы условную компиляции управляемые из Runtime. И при их изменении инвалидируй скомпилированный код использовавший их и компилируй заново. Ан нет. Тут кофеварка непричём. Подобный антипаттерн еще легче воспроизводить в языках и системах с двухэтапной компилляцией. А как вариант можно сделать как в ojdbc. Собрать два варианта библиотек. ojdbc_g где включено JUL и ojdbc где вызовы логгеров отсутствуют. В конце-концов манипулирование логами уровня трейс это достаточно специфичная задача и ее можно вынести в цикл конфигурирования приложения. Управляемая компилляция из Runtime это мега-круто но ненужно. Это ... как ипошить по птичкам из САУ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 14:51 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
maytonТут кофеварка непричём. Подобный антипаттерн еще легче воспроизводить в языках и системах с двухэтапной компилляцией. Ну рвет твои шаблоны экстремальное логгирование. Но это не значит, что это что-то не реализуемое. В принципе, при наличии многопоточного логгера и независимого вввода-вывода для лога. Можно добиться того, что основной поток будет испытывать минимальные осложнения от включения-выключения логгирования на лету. Основной оверхед будет в генерации параметров для log.debug(...) и т.п. Собственно есть некоторый плюс от этого - меньше возмущений при включении, проще поймать плавающий баг. Но если нужна максимальная производительность, то надо убирать генерацию параметров. А это без динамического компилирования - только компиляцией для всех уровней. Каждого класса. И соответствующего class loader. Самое смешное, что в кофемашине, обычно, есть динамическая компиляция. Но программиста до нее не допускают. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 15:01 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
DymytryПойду изучать исходники библиотек логгирования. Значит, слова на объяснения потрачены зря, потому что у афтара желание заниматься фигнёй не пропало. Надо изучать руководства по библиотекам логирования, из них можно много чего узнать для пользования. Нет большого смысла в изучении исходников, т.к. можно смело предположить, что авторы популярных библиотек умеют программировать не хуже, чем афтар ненужного теста для их изобличения, раз логирование для него непривычно. Сергей АрсеньевIMHO логгирование показывает весь блеск и нищету кофе-машины. Мне оно показывает только результат логирования. Блеск и нищета если и есть, то не интересуют. Да, забыл. При выводе по формату на скорость может влиять выбор форматов. Например, в log4j для даты (%d) автор рекомендует один из форматов - ABSOLUTE, DATE, ISO8601. Можно задать любой, представимый с помощью SimpleDateFormat, но другие по мнению автора медленнее. Он очевидно измерял, а я нет и эту рекомендацию соблюдаю не всегда, больше обращаю внимание на удобство. Также он предупреждает о возможной медлительности элементов формата C, F, l, L, M. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 15:47 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Сергей АрсеньевОсновной оверхед будет в генерации параметров для log.debug(...) и т.п.Можно озвучить экзотическую конфигурацию, где ввод-вывод перестал быть узким местом?Самое смешное, что в кофемашине, обычно, есть динамическая компиляция. Но программиста до нее не допускают. :)А вы уже научились использовать серверную JVM? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 17:36 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
К вопросу об охрененных затратах на обработку параметров: Код: plaintext 1. 2. 3. 4. 5. 6. Test.java Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. log4j.xml Код: xml 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 17:59 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
В предыдущем примере уровень логирования был "trace", ставим "off" ничего более не меняя: Код: plaintext 1. 2. 3. 4. 5. 6. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 18:03 |
|
||
|
Нетормозящее логирование в Джаве.
|
|||
|---|---|---|---|
|
#18+
Basil A. SidorovМожно озвучить экзотическую конфигурацию, где ввод-вывод перестал быть узким местом? Если вывод в журнал идет на отдельный канал ввода-вывода с независимым массивом дисков и основной поток занят работой, а не только сбросом информации в журнал. То могут быть ситуации, когда ввод-вывод журнала не будет узким местом. Но конечно не панацея. Basil A. SidorovСамое смешное, что в кофемашине, обычно, есть динамическая компиляция. Но программиста до нее не допускают. :)А вы уже научились использовать серверную JVM? Нет. Я конечно представляю себе как встроить препроцессор который будет высматривать в коде макросы условной компиляции перед передачей их javac и как устроить инвалидацию загруженных классов в класслоадере и подсовывание прошедших компиляцию через препроцессор. Но чисто теоретически. На практике до такой фигни руки не доходили. И вряд ли дойдут. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2015, 10:09 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=39104936&tid=2124392]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
65ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
77ms |
get tp. blocked users: |
1ms |
| others: | 221ms |
| total: | 411ms |

| 0 / 0 |
