Skip to content

[Yaroslavzev] Homework #105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
benchmark-ips (2.13.0)
benchmark-malloc (0.2.0)
benchmark-memory (0.2.0)
memory_profiler (~> 1)
benchmark-perf (0.6.0)
benchmark-trend (0.4.0)
coderay (1.1.3)
date (3.3.4)
diff-lcs (1.5.1)
fasterer (0.11.0)
ruby_parser (>= 3.19.1)
json (2.7.2)
kalibera (0.1.2)
memoist (~> 0.16)
rbzip2 (~> 0.3)
language_server-protocol (3.17.0.3)
memoist (0.16.2)
memory_profiler (1.0.1)
method_source (1.1.0)
minitest (5.22.3)
parallel (1.24.0)
parser (3.3.1.0)
ast (~> 2.4.1)
racc
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
racc (1.7.3)
rainbow (3.1.1)
rbzip2 (0.3.0)
regexp_parser (2.9.0)
rexml (3.2.6)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-benchmark (0.6.0)
benchmark-malloc (~> 0.2)
benchmark-perf (~> 0.6)
benchmark-trend (~> 0.4)
rspec (>= 3.0)
rspec-core (3.13.0)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-support (3.13.1)
rubocop (1.63.4)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.3)
parser (>= 3.3.1.0)
rubocop-performance (1.21.0)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-prof (1.7.0)
ruby-progressbar (1.13.0)
ruby_parser (3.21.0)
racc (~> 1.5)
sexp_processor (~> 4.16)
sexp_processor (4.17.1)
stackprof (0.2.26)
unicode-display_width (2.5.0)
vernier (1.0.0)

PLATFORMS
arm64-darwin-23
x86_64-darwin-21

DEPENDENCIES
benchmark-ips
benchmark-memory
date
fasterer
json
kalibera
memory_profiler
minitest
pry
rspec-benchmark
rubocop-performance
ruby-prof
stackprof
vernier (~> 1.0)

RUBY VERSION
ruby 3.2.4p170

BUNDLED WITH
2.3.7
37 changes: 23 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
### Note
*Для работы скрипта требуется Ruby 2.4+*

_Для работы скрипта требуется Ruby 2.4+_

# Задание №2

В этом задании нужно оптимизировать программу из первого задания, но теперь с фокусом на оптимизацию памяти.

## Бюджет

Программа не должна потреблять больше **70Мб** памяти при обработке файла `data_large` в течение всей своей работы.

## Подсказки

Из бюджета очевидно, что мы не можем ни считывать файл в память целиком, ни накапливать в памяти данные по пользователям.

Значит, программу нужно переосмыслить и написать в "потоковом" стиле - когда мы читаем исходный файл строку за строкой и сразу же на ходу пишем файл с результатами.
Expand All @@ -16,17 +20,17 @@

Можем считать, что все сессии юзера всегда идут одним непрерывным куском. Нет такого, что сначала идёт часть сессий юзера, потом сессии другого юзера, и потом снова сессии первого.


## План работы

В этот раз переработка потребуется кардинальная, так что нужно сделать два этапа

- перевести программу на потоковый подход так чтобы она прошла тесты
- профилировать получившуюся программу рассмотренными инструментами и оптимизировать память ещё сильнее, сделать две-три итерации по фреймворку оптимизации и написать `case-study`
- когда закончите, сделайте замер времени работы программы; получилось ли быстрее чем при оптимизации по процессору в первом задании?


## Как измерять кол-во использованной памяти
В фидбек-лупе можно получать кол-во памяти *в конце* выполнения программы:

В фидбек-лупе можно получать кол-во памяти _в конце_ выполнения программы:

```ruby
puts "MEMORY USAGE: %d MB" % (`ps -o rss= -p #{Process.pid}`.to_i / 1024)"
Expand All @@ -35,37 +39,42 @@ puts "MEMORY USAGE: %d MB" % (`ps -o rss= -p #{Process.pid}`.to_i / 1024)"
После успешной оптимизации дополнительно нужно профилировать программу с помощью `valgrind massif visualizer` и проверить, что память укладывается в бюджет не только в конце работы программы, но и в течение вообще всего времени работы.

## Сдача задания

Для сдачи задания нужно форкнуть этот проект, сделать `PR` в него и прислать ссылку для проверки.

В `PR`

- должны быть внесены оптимизации в `task-2.rb`;
- должен быть файл `case-study.md` с описанием проделанной оптимизации;
- в описании должен быть скриншот из `valgrind massif visualizer`, на котором видно, что программа укладывается в бюджет на протяжении всего времени исполнения;
- в описание `PR` добавьте чеклист и отметьте, что из него сделали; для получения максимальной пользы надо отметить всё.

## Checklist
- [ ] Построить и проанализировать отчёт гемом `memory_profiler`
- [ ] Построить и проанализировать отчёт `ruby-prof` в режиме `Flat`;
- [ ] Построить и проанализировать отчёт `ruby-prof` в режиме `Graph`;
- [ ] Построить и проанализировать отчёт `ruby-prof` в режиме `CallStack`;
- [ ] Построить и проанализировать отчёт `ruby-prof` в режиме `CallTree` c визуализацией в `QCachegrind`;
- [ ] Построить и проанализировать текстовый отчёт `stackprof`;
- [ ] Построить и проанализировать отчёт `flamegraph` с помощью `stackprof` и визуализировать его в `speedscope.app`;
- [ ] Построить график потребления памяти в `valgrind massif visualier` и включить скриншот в описание вашего `PR`;
- [ ] Написать тест, на то что программа укладывается в бюджет по памяти

- [x] Построить и проанализировать отчёт гемом `memory_profiler`
- [x] Построить и проанализировать отчёт `ruby-prof` в режиме `Flat`;
- [x] Построить и проанализировать отчёт `ruby-prof` в режиме `Graph`;
- [x] Построить и проанализировать отчёт `ruby-prof` в режиме `CallStack`;
- [x] Построить и проанализировать отчёт `ruby-prof` в режиме `CallTree` c визуализацией в `QCachegrind`;
- [x] Построить и проанализировать текстовый отчёт `stackprof`;
- [x] Построить и проанализировать отчёт `flamegraph` с помощью `stackprof` и визуализировать его в `speedscope.app`;
- [x] Построить график потребления памяти в `valgrind massif visualier` и включить скриншот в описание вашего `PR`;
- [x] Написать тест, на то что программа укладывается в бюджет по памяти

Не нужно включать в `PR` выводы всех этих отчётов, просто используйте каждый хотя бы по разу в вашем `Case-study`.

## Формат шагов case-study

Каждый шаг оптимизации в `case-study` должен содержать четыре составляющих:

- какой отчёт показал главную точку роста
- как вы решили её оптимизировать
- как изменилась метрика
- как изменился отчёт профилировщика

## Заметки

- Не отключайте GC при вычислении метрики
- Отключайте профилировщик при вычислении метрики
- Используйте все описанные инструменты и отчёты хотя бы по разу – научитесь с ними работать!
- Вкладывайтесь в удобство разработки и скорость фидбек-лупа!

Loading