Проанализируем этим отчетом затрачиваемое время выполнения (режим wall_time)
Measure Mode: wall_time
Thread ID: 70208069025840
Fiber ID: 70208065413220
Total: 0.161745
Sort by: self_time
%self total self wait child calls name
19.77 0.032 0.032 0.000 0.000 20000 String#split
16.45 0.125 0.027 0.000 0.098 5 Array#each
Из отчета видно, что больше всего времени мы тратим на разбиение строк(String#split) именно эта функция первый кандидат на улучшение, если нам не будет хватать скорости обработки. Как вариант можно попробовать заменить связку File.readlines + split на парсинг CSV
Следующий "пожиратель" скорости это Array#each, который занимает 16.45% времени выполнения, но при этом вызывается всего 5 раз. Как вариант оптимизации, можно попробовать сократить один вызов each за счет отказа от отдельного прохода для выборки пользователей в масcив users, а потом обход users для создания user_object
Проанализируем этим отчетом потребление процессора (режим cpu_time)
В этом отчете первый кандидат на улучшение Array#each 80.94% в колонке %Total. Но 16.37% в колонке %Self подсказывают, что большую часть времени происходит ожидание других методов, из которых самый ресурсоемкий это String#split 20.73%
Еще раз проанализируем этим отчетом затрачиваемое время выполнения (режим wall_time)
А из этого отчета, получается, что самый долгий метод это collect_stats_from_users, что идет в разрез с выводами из отчета 1!
Еще раз проанализируем этим отчетом затрачиваемое время выполнения (режим wall_time)
А из этого отчета, получается, что самый долгий метод это parse_file и дальше цепочка замедляющих его вызовов выглядит как Array#each -> calc_stat
Результат профилирования работающей программы выглядит вот так
# sudo rbspy record --pid 66589
Time since start: 46s. Press Ctrl+C to stop.
Summary of profiling data so far:
% self % total name
68.70 100.00 <c function> - unknown
6.66 7.85 block in create_users_objects - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
6.07 31.39 calc_stat - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
3.58 10.17 parse_session - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
2.58 3.58 block in dates - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
1.97 19.18 block in parse_file - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
1.91 5.42 block in find_all_browsers - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
1.52 1.52 block in work - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
1.47 2.02 block in used_ie - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
1.39 1.39 block in count_browsers - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
1.13 32.52 block in collect_stats_from_users - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
0.87 1.15 parse_user - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
0.48 1.43 block in browsers_list - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
0.33 0.78 block in time_from_sesions - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
0.30 0.30 initialize - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
0.28 0.28 block in always_used_chrome - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
0.17 11.66 dates - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
0.17 1.67 time_from_sesions - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
0.15 0.37 longest_session - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
0.11 5.48 browsers - /Users/vikont/RoR_Project/thinknetica/RailsOptimization/task-2/task-2.rb
Wrote raw data to /Users/vikont/.cache/rbspy/records/rbspy-2019-03-24-6UxKcbpDNr.raw.gz
Writing formatted output to /Users/vikont/.cache/rbspy/records/rbspy-2019-03-24-6eLtsXXH6Z.flamegraph.svg
График дает данные, не противоречащие с отчетом ruby-prof в режиме CallStack, которые мы получили выше.

После добавления в проект прогресбара он начал путаться в отчетах профилировщиков, поэтому его отображение я сделал опциональным. Он отображается при запуске скрипта с опцией -p. Данная функциональность релизованна при помощи гема slop.
Отдельно хочу отметить, что построение сквозного прогресбара для всей программы явно не самое простое дело - надо выбрать единую метрику и как-то отслеживать ее прогресс. Теперь стало понятнее почему прогрессбары в некоторых программах могут зависать подолгу на одном проценте, а потом "пролетать" до конца. И более понятно почему многие линуксовые программы показывают отдельные прогресбары на каждую элементарную опирацию. Собственно по второму пути и пошел я.
ruby start.rb -p
Read data from file:: |=================================================================================================================================|
Count uniq browsers:: |=================================================================================================================================|
Create users:: |========================================================================================================================================|
Colculate stats:: |=====================================================================================================================================|
Read data from file:: |=================================================================================================================================|
Count uniq browsers:: |=================================================================================================================================|
Create users:: |========================================================================================================================================|
Colculate stats:: |=====================================================================================================================================|
Научиться пользоваться Valgrind massif с massif-visualizer. Построить профиль использования памяти для итоговой версии вашей программы и добавить скриншот в PR
График утилизации памяти при помощи massif-visualizer показывает линейный рост - вот и славно!




