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

Homework 1 #133

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

Conversation

IgorArkhipov
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 👍

expect { work('data100.txt') }.to perform_at_least(3550).within(measurement_time_seconds).warmup(warmup_time_seconds).ips
end

it 'performs linear' do
Copy link
Collaborator

Choose a reason for hiding this comment

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

раз оно линейно работает, можно довольно точно аппроксимировать

то есть если полный объём должен обработаться за 30 секунд, то 1/100 объёма за ~~ 300мс, соответственно можно бы один какой-то вместо 3ёх спеков спокойно оставить

browser = session['browser']
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, SortedSet для сбора уникального и отсортированного множества


### Ваша находка №1
- какой отчёт показал главную точку роста:
* ruby-prof в режиме Flat с профилем на 10.000 строк указал на большее время проведенное внутри метода Array#select: 86.59% времени при 1536 вызовах. Это и есть наша первая точка роста. На втором месте был Array#all? с 4,36% времени и 10.000 вызовами. На третьем месте был Array#each с 4,3% времени и 10 вызовами
Copy link
Collaborator

Choose a reason for hiding this comment

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

надо на одном чём-то фокусироваться. Добавлять в одну пачку сразу несколько изменений (all, each) - антипаттерн, тк не понятно что как сработало

* ruby-prof в режиме Flat с профилем на 10.000 строк указал на большее время проведенное внутри метода Array#select: 86.59% времени при 1536 вызовах. Это и есть наша первая точка роста. На втором месте был Array#all? с 4,36% времени и 10.000 вызовами. На третьем месте был Array#each с 4,3% времени и 10 вызовами
- как вы решили её оптимизировать:
* число вызовов говорит нам о том, что мы много раз обходим один и тот же массив сессий, чтобы найти в нем те или иные данные, соответствующие пользователям. Мы можем переписать этот цикл так, чтобы мы не начинали обход всех сессий заново по каждому пользователю, а прошли весь массив один раз, и уже внутри этого обхода сопостовляли текущую сессию с тем или иным пользователем, обновляя статистику для него
- как изменилась метрика:
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) благодаря бесконечным поискам по массиву

- как вы решили её оптимизировать:
* число вызовов говорит нам о том, что мы много раз обходим один и тот же массив сессий, чтобы найти в нем те или иные данные, соответствующие пользователям. Мы можем переписать этот цикл так, чтобы мы не начинали обход всех сессий заново по каждому пользователю, а прошли весь массив один раз, и уже внутри этого обхода сопостовляли текущую сессию с тем или иным пользователем, обновляя статистику для него
- как изменилась метрика:
* время выполнения для 10.000 строк сократилось с 0.72 сек до 0.1 сек
Copy link
Collaborator

Choose a reason for hiding this comment

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

на следующую итерацию лучше было бы взять файл побольше, чтобы программа успевала покрутиться секунд 5


### Ваша находка №2
- какой отчёт показал главную точку роста:
* из-за наличия нескольких вызовов метода each необходимо было воспользоваться другим режимом вывода информации профилировщиком, например в виде HTML таблицы вызовов и зависимостей методов (ruby-prof GraphHtmlPrinter). Больше всего вызовов each происходило внутри метода collect_stats_from_users. Это станет нашей второй точкой роста.
Copy link
Collaborator

Choose a reason for hiding this comment

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

плюс за то, чтобы уточнить что откуда именно вызываются общие методы типа all, each

- как вы решили её оптимизировать
* как мы видим, число вызовов each внутри этого метода корреллирует напрямую с множественными вызовами самой collect_stats_from_users. Для сбора разной статистики по разным категориям мы каждый раз снова вызываем метод и снова обходим всех имеющихся пользователей, чтобы найти соответствия. Придется провести рефакторинг, ведь всю информацию можно получить из данных о сессиях для каждого пользователя за один раз. Стоит объединить все отдельные вызываемые блоки в один большой, который мы и передадим в collect_stats_from_users для выполнения над каждым пользователем
- как изменилась метрика
* время выполнения для 10.000 строк осталось прежним
Copy link
Collaborator

Choose a reason for hiding this comment

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

потому что уже слишком маленький файл и слишком короткое время

- какой отчёт показал главную точку роста
* к сожалению, ни один следующий отчет не показал другие проблемы помимо нескольких процентов на ту или иную операцию. Единственное подозрение упало снова на each, где всегда происходит почти все действие. Я стал заново проверять циклы и операции внутри, чтобы увидеть, что можно улучшить на глаз, возможно я пропустил какое-то преобразование, все еще не подключив линтер к проекту. Смутила строчка `users_objects = users_objects + [user_object]`. Зачем каждый раз перезаписывать массив пользователей, если мы хотим просто добавлять каждый новый элемент в конец?
- как вы решили её оптимизировать
* `users_objects << user_object`
Copy link
Collaborator

Choose a reason for hiding this comment

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

эта строка на самом деле обеспечивает много тормозов, потому что супер неэффективно работает с памятью; но это больше в тему 2го ДЗ. Но это более заметно на большем объёме данных

- какой отчёт показал главную точку роста
* к сожалению, ни один следующий отчет не показал другие проблемы помимо нескольких процентов на ту или иную операцию. Единственное подозрение упало снова на each, где всегда происходит почти все действие. Я стал заново проверять циклы и операции внутри, чтобы увидеть, что можно улучшить на глаз, возможно я пропустил какое-то преобразование, все еще не подключив линтер к проекту. Смутила строчка `users_objects = users_objects + [user_object]`. Зачем каждый раз перезаписывать массив пользователей, если мы хотим просто добавлять каждый новый элемент в конец?
- как вы решили её оптимизировать
* `users_objects << user_object`
Copy link
Collaborator

Choose a reason for hiding this comment

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

эта строка на самом деле обеспечивает много тормозов, потому что супер неэффективно работает с памятью; но это больше в тему 2го ДЗ

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