Sergii Tsypanov: "Tricky enterprise"
-
Upload
logeeknightukraine -
Category
Technology
-
view
92 -
download
1
Transcript of Sergii Tsypanov: "Tricky enterprise"
![Page 1: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/1.jpg)
www.luxoft.com
TRICKY ENTERPRISE
![Page 2: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/2.jpg)
www.luxoft.com
Пара слов обо мне
- работаю в «Люксофте» с 2013 г.
- пишу на Java
- люблю разбираться с проблемами производительности
Связаться со мной можно
- написав на корпоративную почту [email protected]
- написав на личную почту [email protected]
- написав ВК https://vk.com/sergei.tsypanov
- написав ФБ https://www.facebook.com/sergei.tsypanov
![Page 3: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/3.jpg)
www.luxoft.com
Вычислительная сложностьКаноническое определение звучит так:
Вычислительная сложность — понятие в информатике и теории алгоритмов, обозначающее функцию зависимости объёма работы, которая выполняется некоторым алгоритмом, от размера входных данных.
https://ru.wikipedia.org/wiki/Вычислительная_сложность
![Page 4: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/4.jpg)
www.luxoft.com
Итак, разминка
Ваши мысли?
![Page 5: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/5.jpg)
www.luxoft.com
А так?
Для пропуска if-блока необходимо и достаточно, чтобы один из операндов был false
![Page 6: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/6.jpg)
www.luxoft.com
Меняем порядок операндов
… а запрос обернём в предикат (можно и в метод, но предикат – это функционально, стильно, модно, молодёжно)
![Page 7: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/7.jpg)
www.luxoft.com
Пример посерьёзнее
В базу один за другим летят три запроса, при том, что далеко не всегда все три необходимы.
![Page 8: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/8.jpg)
www.luxoft.com
Почему так? Или пятиминутка скучной теории
В худшем случае мы ничего не теряем
В лучшем случае достаточно вызвать лишь одни метод
![Page 9: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/9.jpg)
www.luxoft.com
Так лучше
![Page 10: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/10.jpg)
www.luxoft.com
1 ПРАВИЛО КЛУБА:
ЕСЛИ МЕДЛЕННОЕ ДЕЙСТВИЕ МОЖНО ОТЛОЖИТЬ – ОТЛОЖИ ЕГО.ВОЗМОЖНО, ДЕЛАТЬ ЕГО ВОВСЕ НЕ ПРИДЁТСЯ.
Действия лучше выполнять в порядке возрастания их сложности.
![Page 11: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/11.jpg)
www.luxoft.com
Едем дальше
«Понабирали по объявлению» (с)
![Page 12: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/12.jpg)
www.luxoft.com
Присмотрись внимательнее
Количество обращений к репозиторию равно количеству DTO в списке
Чтобы отбросить повторяющиеся сущности, используется Set
Множественные запросы к БД?
HashSet там где достаточно ArrayList-а?
Не отчаивайся, %USERNAME% $USER, выход есть
![Page 13: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/13.jpg)
www.luxoft.com
Грузите апельсины бочками
Посчитаем для списка из 10 ID…
![Page 14: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/14.jpg)
www.luxoft.com
Разница почти в 10 раз
Запросы в цикле
Один запрос
![Page 15: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/15.jpg)
www.luxoft.com
Почему так? Или пятиминутка скучной теории
Что происходит под капотом?
1 Получаем сессию2 Открываем транзакцию
3 Работаем
4 Завершаем транзакцию
5 Закрываем сессию
Это шаблон session-per-request (https://developer.jboss.org/wiki/Sessionsandtransactions)
![Page 16: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/16.jpg)
www.luxoft.com
Почувствуйте разницу…
Пять указанных шагов выполняются при каждом вызове repository.findOne(),
т. е. вычислительная сложность равна О(n)
При вызове repository.findAll(Iterable<ID>)
пять указанных шагов выполняются всегда один раз,
т. е. вычислительная сложность равна О(1)
![Page 17: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/17.jpg)
www.luxoft.com
2 ПРАВИЛО КЛУБА:
ГРАБЬ, ВОРУЙ, …
СОБИРАЙ И ВЛАСТВУЙ.
Однотипные действия, которые выполняются в цикле, часто можно выполнить за один проход, особенно когда речь идёт о запросах в БД.
![Page 18: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/18.jpg)
www.luxoft.com
Внезапно вернёмся к первому примеру
Таким мы его запомнили:
![Page 19: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/19.jpg)
www.luxoft.com
А что если…
…его можно сделать ещё чуточку лучше?
Самую малость…
![Page 20: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/20.jpg)
www.luxoft.com
А что это у нас в третьей строке?
У свеженайденной сущности мы берём сущность-дочку, а потом – сущность-внучку.
…дочка за внучку, внучка за Жучку, и вытащили они – нет, не репку, – а полновесный OutOfMemoryError…
![Page 21: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/21.jpg)
www.luxoft.com
Шутка,
OutOfMemoryError на таком примере не выловить, однако это вполне жизненный пример анти-паттерна под замысловатым названием Circuitous Treasure Hunt.
Его определение: Occurs when an object must look in several places to find the information that it needs. If a large amount of processing is required for each look (i. e. a database access), performance will suffer.
Способ борьбы прост: не размазывайте логику.
![Page 22: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/22.jpg)
www.luxoft.com
Выход есть
Достанем рейтинг напрямую, минуя дочку и внучку
Подправим предикат
![Page 23: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/23.jpg)
www.luxoft.com
Измерим
До
После
![Page 24: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/24.jpg)
www.luxoft.com
Чё, 90 миллисекунд? Серьёзно?
![Page 25: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/25.jpg)
www.luxoft.com
Пятиминутка арифметической объективности
1 проход = 90 мс ≈ 1 фигня
10 проходов= 900 мс ≈ 1 с
100 проходов= 9000 мс = 9 с
1000 проходов= 90000 мс = 90 с = 1,5 минуты
С уважением,
ваш Кэп
![Page 26: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/26.jpg)
www.luxoft.com
3 ПРАВИЛО КЛУБА:
КОСИ И ЗАБИВАЙ …
НЕ ДЕЛАЙ ЛИШНЮЮ РАБОТУ ТАМ, ГДЕ ЕЁ МОЖНО НЕ ДЕЛАТЬ.
ДЕЛАЙ ВСЁ В ОДНОМ МЕСТЕ.
![Page 27: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/27.jpg)
www.luxoft.com
Несложный, но важный пример
![Page 28: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/28.jpg)
www.luxoft.com
Что скажете?
отсеиваем лишнее
и ещё раз отсеиваем лишнее
А теперь, внимание, вопрос.
Что мешает выбрать нужные данные сразу?
Можете ли вы с первого взгляда понять, что делают последние 3 строки?
![Page 29: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/29.jpg)
www.luxoft.com
Переложим логику на мощные плечи БД
Обратите внимание, насколько лаконичнее и выразительнее стал код
![Page 30: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/30.jpg)
www.luxoft.com
4 ПРАВИЛО КЛУБА:
НЕ ДЕЛАЙТЕ ТОГО, ЧТО МОЖЕТ ЗА ВАС СДЕЛАТЬ БД.
Если задача состоит в поиске данных и отсеивании лишнего – делайте это с помощью базы. Она специально заточена под это.
![Page 31: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/31.jpg)
www.luxoft.com
На мой взгляд, самый необычный пример
![Page 32: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/32.jpg)
www.luxoft.com
Внезапно
Транзакция открывается как для «хороших», так и для «плохих» данных.Если данные плохие, то транзакция тут же откатывается.
А зачем нам в таком случае транзакция?
Achtung !!!
![Page 33: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/33.jpg)
www.luxoft.com
Что можно с этим сделать?Испечём «Наполеон»: всю транзакционную логику перенесём во внутренний сервис, а всю логику проверки оставим во внешнем сервисе:
Транзакция открывается только тогда, когда она необходима
![Page 34: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/34.jpg)
www.luxoft.com
Считаем
До
После
![Page 35: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/35.jpg)
www.luxoft.com
«Наполеон», он же шаблон Service Layers
https://en.wikipedia.org/wiki/Service_layers_pattern
• проще писать
• легче читать
• проще тестировать
• легче поддерживать
• проще рефакторить
И это просто вкусно
![Page 36: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/36.jpg)
www.luxoft.com
5 ПРАВИЛО КЛУБА:
РАЗДЕЛЯЙ И ВЛАСТВУЙ.
УВЕЛИЧИВ КОЛИЧЕСТВО СЛОЁВ, ПРИЛОЖЕНИЕ ЛЕГЧЕ ТЕСТИРОВАТЬ И ОНО (В НЕКОТОРЫХ СЛУЧАЯХ) СТАНОВИТСЯ БОЛЕЕ ОТЗЫВЧИВЫМ.
![Page 37: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/37.jpg)
www.luxoft.com
Лирическо-логическое отступление[режим-капитана-очевидности-вкл]
В JVM существует сборщик мусора (СМ), который включается, когда приложению не хватает памяти.
Иногда работа СМ приводит к stop-the-world задержкам в работе приложения.СМ освобождает память и не даёт приложению голодать, но всё имеет свою цену.В обмен на помощь в освобождении памяти СМ берёт дань процессорным временем.
Таким образом, если доступная вычислительная мощность равна 1, а СМ отнимает у нас х, то приложению остаётся лишь 1 - х вычислительной мощности.
Отсюда вывод: производительность можно повысить, если уменьшить дань, забираемую СМ
[режим-капитана-очевидности-выкл]
![Page 38: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/38.jpg)
www.luxoft.com
Немного отвлечёмся от вычислительной сложностиНебольшое пояснение: это общий предок для около 50 сущностей одного из наших приложений.Метод includeInAudit() вызывается при изменении значений некоторых полей, и вызывается он очень часто
![Page 39: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/39.jpg)
www.luxoft.com
Вернёмся к нашим баранамНа основе реальных событий: в результате 1 действия 1 пользователя данный метод вызывается 3,5 тыс. раз
И при каждом вызове метода создаётся HashSet…
![Page 40: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/40.jpg)
www.luxoft.com
Пятиминутка арифметики:
Пустой HashSet в 64-разрядной JVM «весит» 240 байт*.
Путём сложнейших вычислений определим, что 3,5 тыс. пустых (берём по нижней границе) HashSet-ов «весят» 820 кБ.
И это 1 действие 1 пользователя…
* Накладные расходы памяти у коллекций https://habrahabr.ru/post/159557/
![Page 41: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/41.jpg)
www.luxoft.com
Присмотримся внимательнее…и обнаружим, что по завершении цикла переменная drafts может иметь только 4 состояния:
• пустая коллекция
• коллекция, содержащая OLD_DRAFT
• коллекция, содержащая NEW_DRAFT
• коллекция, содержащая обе записи
![Page 42: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/42.jpg)
www.luxoft.com
Перепишем определим все
возможные состояния
вместо добавления объектов
используем уже созданные коллекции
![Page 43: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/43.jpg)
www.luxoft.com
6 ПРАВИЛО КЛУБА:
ЧИСТО НЕ ТАМ, ГДЕ УБИРАЮТ,А ТАМ, ГДЕ НЕ МУСОРЯТ.
Кэшируйте всё, что можно и не превращайте приложение в помойку.
![Page 44: Sergii Tsypanov: "Tricky enterprise"](https://reader036.fdocuments.net/reader036/viewer/2022062302/5871b9341a28ab55058b5203/html5/thumbnails/44.jpg)
www.luxoft.com
СПАСИБО ЗА ВНИМАНИЕ
И ДЕРЖИТЕ ПОРОХ СУХИМ БАЗУ ПРОГРЕТОЙ