Conversation
d3454e4 to
9c09458
Compare
| def stream | ||
| Enumerator.new do |yielder| | ||
| loop do | ||
| yielder << Oj.load(object) |
| <%= render "delimiter" %> | ||
| <% end %> | ||
| <%= render 'shared/pagination' %> | ||
| <%= render partial: 'trip', collection: @trips, spacer_template: 'delimiter' %> |
There was a problem hiding this comment.
👍 лайк за collection и spacer_template
| @total_count = Trip.where(from: @from, to: @to).count | ||
| @trips = Trip.where(from: @from, to: @to) | ||
| .order(:start_time) | ||
| .limit(@per).offset(@per * (@page - 1)) |
There was a problem hiding this comment.
пагинация limit offset в целом имеет для меня плохую репутацию (вроде бы про это что-то было в лекциях)
Trip.where(from: @from, to: @to).count при большом кол-ве трипов может начать жёстко тормозить, что негативно скажется на времени загрузки страницы (у нас тут их так много нет, но сам паттерн такой пагинации потенциально проблемный)
|
|
||
| Конечная метрика: время выполнения импорта файла `fixtures/large.json` должно укладываться в 60 сек. | ||
| Для того, чтобы понимать, дают ли мои изменения положительный эффект на быстродействие программы я придумала использовать такую метрику: | ||
| 1) обработка файла после внесенных оптимизаций должна быть меньше, чем до оптимизации |
There was a problem hiding this comment.
сорри за духоту, но это не метрика; метрика это число какое-то, характеризующее твою систему. В данном случае ты наверно берёшь за метрику время загрузки файла маленького/среднего (чтобы не ждать large.json)
|
|
||
| ## Предварительная подготовка | ||
|
|
||
| 1) Добавила в проект тесты |
| 4) вынесла в класс DataLoader, перенесла тесты | ||
|
|
||
| Пока выносила обратила внимание что файл считывается в память целиком, также в задании упоминается про файл 1М который весит примерно 3ГБ, перепишем сразу на стриминг | ||
| добавила класс JsonStreamer - собирает объекты и возвращает по одному. Гемы потоковой обработки выглядят сложновато для достаточно простой задачи, возможно они работают быстрее, но этим можно будет озаботиться попозже |
There was a problem hiding this comment.
да честно говоря я пробовал как раз с разными гемами, они все умирали на огромном файле, в итоге пришлось остановиться на вот таком ручном варианте
возможно сейчас какой-то гем и есть рабочий, но в целом это не серебрянная пуля
| 6) large: 3.958625 | ||
| 7) 1M: 38.381950 | ||
| 8) ну тут уже время упирается в стример, без каких либо преобразований он перебирает файл 1M за 34.973238 | ||
| 9) причем потребление памяти на 1М не превышает 8МБ |
| -> Parallel Seq Scan on trips (cost=0.00..23750.00 rows=36 width=34) | ||
| Filter: ((from_id = 10) AND (to_id = 92)) | ||
| (4 rows) | ||
| 4) Избавимся от Seq Scan добавив составной индекс. Так как поиск идет всегда по (from_id, to_id). Также сделаем сразу сортированный индекс по времени |
|
|
||
| ## Защита от регрессии производительности | ||
| 1) для импорта данных был написан тест на проверку времени выполнения | ||
| 2) для отображения расписания был бы написан тест на N+1 запрос, если бы rspec-sqlimit был совместим с rails 8.0.1 |
| @@ -0,0 +1,26 @@ | |||
| # Mark existing migrations as safe | |||
| StrongMigrations.start_after = 20250222090128 | |||
There was a problem hiding this comment.
strong_migrations one love
No description provided.