diff --git a/after.png b/after.png new file mode 100644 index 0000000..bc39517 Binary files /dev/null and b/after.png differ diff --git a/before.png b/before.png new file mode 100644 index 0000000..c6b46a0 Binary files /dev/null and b/before.png differ diff --git a/case-study.md b/case-study.md new file mode 100644 index 0000000..e511ec2 --- /dev/null +++ b/case-study.md @@ -0,0 +1,107 @@ +# Case-study оптимизации + +## Актуальная проблема +В нашем проекте тесты (6594) проходят за примерно 5,5 минут на CI (локально около 3 минут). + +Чуть меньше года назад была итерация по ускорению тестов, результат которой: +30 минут -> 4 минуты (CI) +8,5 минут -> 3 минуты (локально) +В первой итерации основные изменения: +вынесла в сиды 2 справочника, объекты которых создавались в каждом тесте +уменьшила вложенность фабрик +вынесла в фикстуры дефолтные фабрики +привела в порядок использование фабрик в самых долгих тестах (let_it_be, build, before_all) + +Локально время не дегрдировало, на CI время поменялось после переезда в Gitlab +Я решила попробовать ускорить тесты еще раз. + +## Формирование метрики +Для того, чтобы понимать, дают ли мои изменения положительный эффект на быстродействие программы я придумал использовать такую метрику: +среднее время выполнения тестов за 3 запуска на локальной машине должно укладываться в 2 минуты + +## Вникаем в детали системы, чтобы найти главные точки роста +Время до оптимизаций: Finished in 3 minutes 7.8 seconds (files took 4.04 seconds to load) + +Для того, чтобы найти "точки роста" для оптимизации я воспользовался rspec, ruby-prof, stackprof, test-prof и другими инструментами, которые мы рассмотрели на лекциях. + +Вот какие проблемы удалось найти и решить + +### Ваша находка №1 +воспользовалась test-prof FPROF=flamegraph, нашла вложенность фабрик, которую можно убрать, начала с накладных +пересмотрела еще раз фабрики, нашла избыточную вложенность, которую можно убрать. Экономит не так много времени, зато уменьшается вложенность +было фабрик: Total: 20290 +стало: Total: 20093 +![before.png](before.png) +![after.png](after.png) + +### Ваша находка №2 +воспользовалась test-prof FPROF=1, нашла часто используемую фабрику с долгим времен создания, убрала лишние поля +фабрика компаний занимает много времени несмотря на свою простоту, посмотрим что внутри: +много sequence и ненужных полей, попробуем убрать и проверить эффект: + + name total top-level total time time per call top-level time +было: company 2075 1268 24.2947s 0.0117s 14.6411s +стало: company 2075 1268 18.5263s 0.0089s 10.9690s + +Проверка времени на текущий момент: Finished in 2 minutes 57 seconds (files took 3.99 seconds to load) + +### Ваша находка №3 +По отчету test-prof FPROF=1 FPROF_VARS=1 находим часто создаваемую фабрику, вынесем ее в фикстуру +Вынесем фикстуру админа в before(:suite) + +user 1629 1604 20.2135s 0.0124s 20.1218s +Total: 19893 +Total top-level: 12747 +Total time: 01:36.860 (out of 03:06.752) +Total uniq factories: 110 + +user 1035 1010 13.4071s 0.0130s 13.3243s +Total: 18057 +Total top-level: 12143 +Total time: 01:28.752 (out of 02:54.755) +Total uniq factories: 110 + +[TEST PROF INFO] AnyFixture usage stats: + +key build time hit count saved time +platform_admin 00:00.040 593 00:24.047 + +### Ваша находка №4 +Вынесем фикстуру forwarder_operator: + +[TEST PROF INFO] AnyFixture usage stats: + +key build time hit count saved time +forwarder_operator 00:00.009 126 00:01.237 + +[TEST PROF INFO] Factories usage + +Total: 17554 +Total top-level: 12020 +Total time: 01:27.353 (out of 02:54.839) +Total uniq factories: 110 + +user 910 885 11.5259s 0.0127s 11.4501s + +Finished in 2 minutes 51.9 seconds (files took 4.2 seconds to load) + +### Ваша находка №5 +Надо бы еще вынести в фикстуру одну авиакомпанию, которая создается почти во всех тестах и пользователя для авиакомпании, тогда кол-во фабрик сократится еще на 1267 + 235 = 1502 +Но так как АК достаточно плотно интегрирована во все тесты и большинство фабрик, то это задача не их простых, поэтому пока оставим как есть + +Даже с внедрением этих изменений не думаю, что удастся уложиться в 120 секунд без распараллеливания +Хотя там еще будет затронуто создание компаний, накладных и пр. Будет видно, только если вынести фикстуру + +### Ваша находка №N +Ну и распараллелим тесты, чтобы ускорить их выполнение: +gem 'parallel_tests' + +rake "parallel:spec[3]" +Took 68 seconds (1:08) +Took 67 seconds (1:07) +Took 63 seconds (1:03) + +вполне себе успех, уложились в бюджет)) + +## Результаты +В результате проделанной оптимизации наконец удалось уложиться в бюджет в 120 секунд на локальной машине