From cd47e4081ebadc989fd01658d0e183187d6565b9 Mon Sep 17 00:00:00 2001 From: "m.oleynik" Date: Wed, 2 Sep 2020 21:42:10 +0300 Subject: [PATCH] case-study --- Readme.md | 67 +++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/Readme.md b/Readme.md index 17abaa1..b4ae36b 100644 --- a/Readme.md +++ b/Readme.md @@ -1,53 +1,52 @@ -# Задание №8 +### Проект #1 -В этом задании вам нужно написать `case-study` о том как вы применили знания, полученные на курсе, к своим проектам. +В этот case study хотел бы включить кейсы из разных проектов, в которых приходилось принимать участие. Один из таких проектов интересен тем, что большАя часть проекта просто [зашифрована](https://www.rubyencoder.com/). Это было сделано предыдущими разработчиками для защиты интеллектуальной собственности (вместо NDA). Приходилось смотреть в логи и по ним понимать, что примерно происходит внутри. -## To start +На этом проекте не было мониторинга и при этом были большие проблемы с оптимизацией. -Для начала напишите немного о своём проекте. +Самой большой точкой роста был N+1 запрос для построения меню. Меню рисовалось на всех страницах приложения, так что это была самая жирная точка роста и от нее надо было избавляться в первую очередь. До кода я добраться не мог. Пришлось [закэшировать](http://rusrails.ru/caching-with-rails-an-overview#keshirovanie-fragmenta) участок кода во вьюхе. -- что за проект -- как долго уже разрабатывается -- как дела с перформансом -- есть ли мониторинг -- можете ли вы навскидку предположить где в проекте есть что оптимизировать -- какова ваша роль в проекте, как давно работаете, чем занимаетесь +``` +- cache product_category do + %li + = link_to "/catalogs/#{product_category.to_param}.html" do + ... +``` -Сделайте `PR` в этот репозиторий, и дорабатывайте его по ходу курса. +Меню меняется редко, поэтому закешировать его - не проблема. +Был момент, когда пришлось захардкодить это меню и вставить чистый html. Это было приемлимо, но решение продержалось недолго. Но как вариант можно использовать. -## Hints +На этом же проекте был автокомплит (в курсе тоже этот кейс упоминался, но я реализовал ограничение от трех букв на фронте, так что запросы на бэк не шли вообще, пока пользователь не ввел три буквы). -Форма `case-study` - свободная. +Еще, что заметно прибавило скорости, так это выставление index'ов на все внешние ключи. Искал отсутствующие индексы с помощью гема (не помню название). -Можно написать в форме интересной технической статьи на Хабр. Потом можно будет и опубликовать. +На проекте я работал один и честно говоря не было времени всерьез заниматься профилированием. -Можно взять за основу форму `case-study` из первого задания. +### Проект #2 -### MVP is OK +Проект достаточно давно разрабатывается. С перфомансом на проекте все хорошо. На этом проекте есть мониторинги: Grafana для железа, PgHero для SQL. На вскидку предполагаю, что на проекте есть много N+1, которые мне еще предстоит оптимизировать. В тестах - каскады в фабриках. -Оптимизация не обязана быть доведена до прода. +1) На этом проекте большой точкой роста является класс, который собирает объекты и потом одним запросом создает сущности в базе. Этот класс был написан еще в 2015 году, но в какой-то момент он исчерпал себя (база растет и теперь при импорте миллиона сущностей память раздувает до ~3gb). -Например, вы рассмотрели какую-нибудь подсистему с `fullstack` точки зрения и придумали как её оптимизировать, сделали `MVP`, получили первые результаты. +``` +Прирост памяти: 2840.6299mb +``` -В таком случаем интересно рассказать об этом. +Это было до 6 рельсов, сейчас переходим на изкоробочное решение `upsert_all/insert_all`. +| | `#upsert_all` | custom class | +| --------------- | ------------- | ------------------------ | +| 10.000 записей | 19.00 MB | 75.84 MB | +| 100.000 записей | 187.62 MB | 756.48 MB | +| 500.000 записей | 931.44 MB | :( - все наглухо зависло | -### О чём интересно рассказать +В качестве профилировщика использовался `memory_profiler`. Объемы потребляемой памяти в сравнении с кастомным классом сократились в **4x**. Эта оптимизация еще не доведена до прода. -- расскажите об актуальной проблеме; -- расскажите, какой метрикой характеризуется ваша проблема; -- если вы работали в итерационном процессе оптимизации, расскажите как вы построили фидбек-луп; -- если пользовались профайлерами - опишите находки, которые сделали с их помощью; -- расскажите, как защитили достигнутый прогресс от деградации; -- прикиньте, сколько денег сэкономила ваша оптимизация: сократили потребление памяти и сэкономили денег на серверах / ускорили ответ сервера и уменьшили bounce-rate / ускорили прогон тестов и улучшили рабочий feedback-loop для всех участников команды...; если сделали что-то полезное, но сложно понять, как это оценить в деньгах, пишите в `Slack`, обсудим; -- если вы сделали много оптимизаций, расскажите о всех! чем больше - тем лучше! если какие-то из них менее интересны, упомяните о них обзорно; +2) Так же на проекте есть кейс (по сути фильтр), который сочетает в себе и [ransack](https://github.com/activerecord-hackery/ransack) и ActiveRecord и чистый SQL. Это достаточно хрупкое место и после добавления нового фильтра кейс начал отрабатывать за минуту. -### Если ничего не приходит в голову +Первым делом обратился к PgHero, он не показал что запрос является точкой роста. Но в логах я заметил лишние запросы типа `Exist?` (запрос в логах был не во всех фильтрах). Я начал искать, где в запросе есть проверки на существование записей и нашел `#any?`. Добавил `#load` и проблема исчезла. Понимаю что это скорее костыль и проблему надо решать по другому (скоре переписать кейс на query-object стиль и оставить что-то одно). -Всегда можно оптимизировать тесты вашего проекта с помощью `test-prof`! (если конечно они уже не доведены до идеала) +3) Это небольшая точка роста на любом проекте, это просто хорошая практика :) +Перечитывая доки, наткнулся на [такой кейс](http://rusrails.ru/debugging-rails-applications#vozdeystvie-logov-na-proizvoditelnost). В итоге написал кастомный коп для этого. -Всегда можно сделать аудит проекта с помощью `sitespeed.io`, `webpagetest`, `pagespeed insights`, `lighthouse` и применить предложенные советы. - -## Как сдать задание - -Сделайте `PR` в этот репозиторий с вашим `case-study`. +4) Прогнал тесты вместе со встроенным профилировщиком `rspec spec --profile`. Он показал несколько самых медленных тестов, в которых была одна общая проблема: создавался объект вне всех `context`, а использовался лишь в одном или нескольких. После переноса `let` в нужный `context` прирост скорости был очень значительный (в некоторых случаях в два раза с 50 до 23 сек). \ No newline at end of file