Conversation
af85665 to
0a83625
Compare
| Я решил исправить эту проблему, оптимизировав эту программу. | ||
|
|
||
| ## Формирование метрики | ||
| Для того, чтобы понимать, дают ли мои изменения положительный эффект на быстродействие программы я придумал использовать такую метрику: Время выполнения программы с частичным объемом данных за вменяемое время |
| 89.15% 89.15% 7.19 7.19 0.00 0.00 3046 Array#select | ||
|
|
||
| ``` | ||
| - Заменил перебор всех сессий на хэш с группированные данных по user_id. В данном конкретном месте алгоритмическая сложность с O(n) изменилась на O(1) |
|
|
||
| ``` | ||
| - Заменил перебор всех сессий на хэш с группированные данных по user_id. В данном конкретном месте алгоритмическая сложность с O(n) изменилась на O(1) | ||
| - Метрика кратно уменьшилась при прогоне теста на перфоманс с средних 5 сек. до 0.4 сек. Это и было самым узким местом программы по всей видимости. |
There was a problem hiding this comment.
это было место которое делало разницу между O(N^2) и O(N)
| %Total %Self Total Self Wait Child Calls Name | ||
| 96.01% 43.30% 0.73 0.33 0.00 0.40 10 Array#each | ||
| ``` | ||
| - Заменил `sessions = sessions + [parse_session(line)] if cols[0] == 'session'` на `sessions = sessions << parse_session(line) if cols[0] == 'session'` |
There was a problem hiding this comment.
не совсем понятно как именно от Array#each пришли именно к этому изменению
обычно можно поковыряться с другими отчётами / порефачить код, чтобы стало всё-таки более конкретно понятно в чём проблема
| ``` | ||
| - Заменил `sessions = sessions + [parse_session(line)] if cols[0] == 'session'` на `sessions = sessions << parse_session(line) if cols[0] == 'session'` | ||
| Известная проблема в ruby. Оператор << позволяет не создавать новую переменную каждый раз, а писать все в существующую. | ||
| - При прогоне теста, среднее значение метрики упало с 0.4 сек. до 0.25 сек. |
There was a problem hiding this comment.
для профилирования лучше несколько секунд хотя бы чтобы runtime был (если мы говорим о процессе, который в целом идёт мнооого секунд)
| %Total %Self Total Self Wait Child Calls Name | ||
| 28.57% 16.02% 0.09 0.05 0.00 0.04 16954 <Class::Date>#parse | ||
| ``` | ||
| - Поправил, Date.parse лишняя обработка. |
| Среднее значение прогода 60_000 строк = 0.3 сек. | ||
| - Среднее значение прогона всего файла с ~30 сек. упало до 27 сек. | ||
| - В отчетах профилировщика эта точка роста перестала быть главной. | ||
| - Вижу еще несколько точек роста, но решил на этом остановится =) |
| end | ||
|
|
||
| describe 'with full file' do | ||
| it 'works under 30 sec' do |
There was a problem hiding this comment.
👍 респект за грамотное название describe и it
| let(:file) { './spec/fixtures/files/dataN.txt' } | ||
|
|
||
| describe 'with partial file' do | ||
| it 'works under 0.4 sec' do |
There was a problem hiding this comment.
в принципе коль скоро мы пришли к линейной сложности, можно прикинуть по линейной зависимости что скажем файл на 1/100 объёма должен выполняться за 300ms и оставить только один такой спек (чтобы не надо было 30 секунд ждать)
No description provided.