Skip to content
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

Optimization CPU #145

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open

Optimization CPU #145

wants to merge 11 commits into from

Conversation

newaaz
Copy link

@newaaz newaaz commented May 5, 2024

No description provided.

@@ -0,0 +1,9 @@
data_large.txt
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


1. Подготовил тест для защиты метрики от деградации. В нём проверяется время выполнения программы, ips и асимптотика *(performance_spec.rb)*
2. Подготовил проверку производительности программы, в которой вычисляется время выполнения программы с (1, 2, 4, 8, 16) * 1000 строк, и проверяется ips на 8 * 1000 строк. В ходе оптимизации программы эти коэффициенты будут увеличиваться *(benchmark.rb)*.
3. Подготовил файлы для профилирования:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 лайк за создание удобства для себя

- stackprof.rb - генеруирует отчёты для командной строки и JSON для speedscope
- work-method.rb - копия оптимизируемой программы, но с отключённым GC и возможностью в виде аргумента задавать файл с разными количествами строк

Благодаря такой подготовке я могу быстро проверять гипотезы при профилировании и тестировать полученные результаты в ходе реального выполнения программы.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

≈ 11.616 × 21852
≈ 253839.792 секунд

Это примерно 253839.792 / 3600 ≈ 70.51 часов.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

- Все профилировщики показывают самое проблемной место - Array#select (**67%**) в котором для каждого пользователя перебирается весь массив сессий, что приводит к асимптотической сложности сложности порядка O(n*m), где n - число пользователей, а m - число сессий.
- Чтобы улучшить производительность создал вспомогательную хэш-таблицу в которой сгруппировал сессии по *user_id*
- Получил значительный прирост в скорости: на 16 000 строках было 7,3сек, стало 0,7сек.
- Данный метод перестал являться точкой роста.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

и тут асимптотика становится лучше, и можно переприкинуть расчёты

### Ваша находка №2
- Ruby-prof: flat, graph, callstack показали следующую точку роста - сложение массивов - Array#+ (**33%**). Это занимает много времени т.к. каждый раз инициализируется новый массив. Сложение вызывается в 3-х местах.
- Использую **map** для обработки users_objects
- 16 000 строк - было 0,7сек, стало 0,5 сек.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хорошо подбирать объём данных так, чтобы программа успевала покрутиться пару секунд. Если она завершается слишком быстро (“не успевает поработать”) могут возникнуть какие-то перекосы (например, на полном объёме основная часть времени тратится в основном цикле, а если данных мало - то большая часть уходит на инициализацию и финализацию, например на чтение из файла и запись потом в файл)

И плюс когда время уже на миллисекунды - больше влияние погрешностей.

В результате проделанной оптимизации наконец удалось обработать файл с данными.
Удалось улучшить метрику системы с 70.51 часов (ориентировочно) до 32 секунд и практически уложиться в заданный бюджет.

Самое главное - сумел организовать рабочий процесс по оптимизации программы с помощью фреймворка оптимизации. Разобрался как формировать и фиксировать метрики, быстро проверять гипотезы и выстраивать эффективный feedback-loop!
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Самое главное - сумел организовать рабочий процесс по оптимизации программы с помощью фреймворка оптимизации. Разобрался как формировать и фиксировать метрики, быстро проверять гипотезы и выстраивать эффективный feedback-loop!

## Защита от регрессии производительности
Для защиты от потери достигнутого прогресса при дальнейших изменениях программы gодготовил тест *(performance_spec.rb)* для защиты метрики от деградации. В нём проверяется время выполнения программы, ips и асимптотика.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

report['usersStats'][user_key] ||= {}
report['usersStats'][user_key] = report['usersStats'][user_key].merge(block.call(user))
end
end

def work
progressbar = ProgressBar.create(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

надо иметь в виду что прогресс-бар может тормозить, особенно если постоянно его дёргать

uniqueBrowsers += [browser] if uniqueBrowsers.all? { |b| b != browser }
end

uniqueBrowsers = sessions.map { |s| s['browser'] }.uniq
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я бы их в Set просто напихивал

Copy link
Collaborator

@spajic spajic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Всё очень чётко сделано, аккуратно, было приятно читать, респект 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants