В этом задании нужно оптимизировать программу из первого задания, но теперь с фокусом на оптимизацию памяти.
Программа не должна потреблять больше 70Мб памяти при обработке файла data_large.txt
в течение всей своей работы.
Для практики можно начать с того чтобы попрофилировать исходную версию по аллокациям. Там заложено очень много неэффективностей - можно на них потренироваться.
- дальше придётся перевести программу на потоковый подход так чтобы она прошла тесты
- профилировать получившуюся программу рассмотренными инструментами и оптимизировать память ещё сильнее, сделать пару итераций по фреймворку оптимизации и добавить их в
case-study
- когда закончите, сделайте замер времени работы программы; получилось ли быстрее чем при оптимизации по процессору в первом задании?
Из бюджета очевидно, что мы не можем ни считывать файл в память целиком, ни накапливать в памяти данные по пользователям.
Значит, программу нужно переосмыслить и написать в "потоковом" стиле - когда мы читаем исходный файл строку за строкой и сразу же на ходу пишем файл с результатами.
Достаточно, чтобы результат совпадал с эталоном как json
-объект, а не строка. Порядок полей в объекте не важен.
Можем считать, что все сессии юзера всегда идут одним непрерывным куском. Нет такого, что сначала идёт часть сессий юзера, потом сессии другого юзера, и потом снова сессии первого.
В фидбек-лупе можно получать кол-во памяти в конце выполнения программы:
puts "MEMORY USAGE: %d MB" % (`ps -o rss= -p #{Process.pid}`.to_i / 1024)"
Ради интереса можно добавить второй Thread
, который будет раз в секунду мониторить память процесса и грохать весь процесс при превышении бюджета.
Так же этот тред может например логать кол-во потребляемой памяти в файл, чтобы можно было увидеть как она изменяется со временем.
Раньше предлагалось заюзать для этих целей Valgrind Massif Visualiser
, но кажется с ним очень много возни, а пользы не так уж много. Реально интереснее и полезнее сделать второй тред.
Надо, как и всегда, сделать MR в этот репозиторий и отправить на проверку.
В MR
должно быть следующее:
- внесены оптимизации в
task2.rb
; - файл
case-study.md
с описанием проделанной оптимизации;
- Потренироваться с
memory_profiler
- Потренироваться с
ruby-prof
в режимеCallTree
c визуализацией вQCachegrind
; - Потренироваться с
stackprof
+CLI
иSpeedscope
- Потренироваться со вторым тредом для мониторинга памяти
Каждый шаг оптимизации в case-study
должен содержать четыре составляющих:
- какой отчёт показал главную точку роста
- как вы решили её оптимизировать
- как изменилась метрика
- как изменился отчёт профилировщика