Как стать автором
Обновить

Ускоряем загрузку рельс

Время на прочтение2 мин
Количество просмотров1.7K
Автор оригинала: Xavier Shay
Несмотря на заголовок, речь пойдет скорее о руби, чем о рельсах. Поэтому я решил разместить этот перевод в блоге руби.

Последние релизы MRI Ruby показывают значительное замедление при подключении файлов.

Например, наше средненькое рельсовое приложение при загрузке делает require около 2200 раз — это где-то совсем в правой части графика. Совсем никуда не годится. На 1.9.2 приложение стартует за 20 секунд, а на 1.9.3 уже 46. Слишком медленно!

Этому есть несколько причин, но главная — алгоритм require, который выглядит примерно вот так:
def require(file)
  $loaded.each do |x|
    return false if x == file
  end
  load(file)
  $loaded << file
end


Все тормоза идут от цикла, и чем больше файлов мы подключаем, тем сильнее все тормозит. Я написал патч для 1.9.3, который заменяет тормозной цикл на что-то подобное:
def require(file)
  return false if $loaded[file] 
  load(file)
  $loaded[file] = true
end

И это дает примерно следующий результат:

Намного приятнее!

Это графики синтетического теста по подключению пустых файлов, но патч дает ускорение и в реальных проектах. Мое приложение теперь грузится около 10 секунд. На 1.9.2 оно грузилось 20. Пустое приложение загружается вообще за 1.1 сек, что даже быстрее, чем в 1.8.7


Как пропатчиться


Тут все достаточно просто, это займет не больше 10 минут, если у вас установлен RVM.
# Сначала замеряем на текущей версии
cd /your/rails/app
time script/rails runner "puts 1"

# Ставим патченный ruby
curl https://gist.github.com/raw/996418/e2b346fbadeed458506fc69ca213ad96d1d08c3e/require-performance-fix-r31758.patch > /tmp/require-performance-fix.patch
rvm install ruby-head --patch /tmp/require-performance-fix.patch -n patched
# ... и идем пить чай — эта штука собиралась 8 минут на моем MBP

# Смотрим как улучшилось время
cd /your/rails/app
rvm use ruby-head-patched
gem install bundler --no-rdoc --no-ri
bundle
time script/rails runner "puts 1"


Чем можно помочь


Мне нужно привлечь как можно больше внимания к патчу, прежде чем его включат в основной транк. Сильно помогло, если бы вы:
  • Попробовали патч на своих приложениях и отписали время выполнения бенчмарков в комменты
  • Посмотрели код в пулл-реквесте на гитхабе (язык С, но я надеюсь что никто не испугается)
  • Попробовали на Windows
  • Репортили баги, которые найдете


Что дальше


Я полагаю, что до включения этого патча в 1.9.3 еще далеко, предстоит много работы, но все же, это первый из многих шагов, направленных на ускорение запуска приложений на рельсах. Есть еще Bundler и RubyGems, которые тратят очень много времени непонятно на что — хотелось бы изучить их внутренности.
Так же я планирую портировать этот патч в JRuby, поскольку там есть похожие проблемы. В Rubinius, кажется, изначально с этим все в порядке.
Теги:
Хабы:
+73
Комментарии23

Публикации

Изменить настройки темы

Истории

Работа

Программист Ruby
8 вакансий
Ruby on Rails
10 вакансий

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн