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

performance optimization #1 #159

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

Conversation

aushev-dev
Copy link

No description provided.

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.

Nice work!


## Формирование метрики
Для того, чтобы понимать, дают ли мои изменения положительный эффект на быстродействие программы я придумал использовать такую метрику:
Время выполнения программы.
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
Для того, чтобы иметь возможность быстро проверять гипотезы я выстроил эффективный `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.

*это был плейсхолдер*

### находка №1 Многократная итерация объекта sessions для создания users_objects
- callstack из ruby-prof
- Одной итерацией собрать необходимые данные в объекте sessions_by_user
- Время выполнения приложения на 15т строк сократилась 7.5 секунд до 0.9 секунд
Copy link
Collaborator

Choose a reason for hiding this comment

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

главное, что сложность O(N^2) -> O(N)

### находка №2 Неэффективный алгоритм с многократными проверками для сбора unique_browsers.
- callstack из ruby-prof
- Было принято решение заменить неэффективный алгоритм с многократными проверками на более оптимизированное решение, использующее встроенные методы Ruby
- Время выполнения приложения на 15т строк сократилась 0.9 секунд до 0.6 секунд
Copy link
Collaborator

Choose a reason for hiding this comment

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

лучше при профилировании в подобных задачах, которые очень долгие давать программе хотя бы несколько секунд покрутиться. Так profile будет более приближен к реальности


### Находка №3: Неэффективное добавление элементов в массивы с использованием оператора конкатенации
- callstack из ruby-prof
- Было принято решение заменить неэффективное добавление элементов в массивы с помощью оператора + на использование метода << (shovel operator). Дополнительно была применена конструкция case для улучшения читаемости и производительности.
Copy link
Collaborator

Choose a reason for hiding this comment

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

лучше стараться избегать соблазна сделат что-то "дополнительно" в одну итерацию.

как только мы сделали больше одного изменения, мы сразу перестаём понимать какое как сработало

### Находка №5: Избыточное использование хешей для представления сессий
- callstack из ruby-prof
- Анализ профилировщика показал, что создание и обработка хешей в методе parse_session занимают значительное время, особенно при большом количестве сессий. Это связано с накладными расходами на создание объектов хешей и доступ к их ключам.
- Было принято решение заменить использование хешей на Struct для представления сессий. Struct предоставляет более легковесную и быструю структуру для хранения данных с фиксированными ключами, что уменьшает время создания объектов и ускоряет доступ к их атрибутам.
Copy link
Collaborator

Choose a reason for hiding this comment

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

ого, кажется впервые вижу такую оптимизацию в этом задании; интересно!


## Результаты
В результате проделанной оптимизации наконец удалось обработать файл с данными.
Удалось улучшить метрику системы с более чем 15 минут обработки файла до 30 секунд и уложиться в заданный бюджет.
Copy link
Collaborator

Choose a reason for hiding this comment

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

там ближе к неделе, чем к 15 минутам

describe 'Task-1 Performance' do
describe '#work method' do
it 'completes the operation within 30 seconds' do
expect { work(file_name: "data_large.txt", progress_bar: false) }.to perform_under(30).sec
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

пользуясь тем, что у нас сложность стала O(N) можно было бы сделать тест побыстрее. Взять например 1% данных и 1% времени

@@ -24,15 +20,11 @@ def parse_user(user)
}
end

Session = Struct.new(:user_id, :session_id, :browser, :time, :date)
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍 👍

browser = session['browser']
uniqueBrowsers += [browser] if uniqueBrowsers.all? { |b| b != browser }
end
unique_browsers = sessions.map { |session| session['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 ещё заюзать

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