Повышение производительности приложения rails 3: лучший рабочий процесс?

#ruby-on-rails #performance #ruby-on-rails-3

#ruby-on-rails #Производительность #ruby-on-rails-3

Вопрос:

Я хочу улучшить производительность своего приложения и начал читать http://guides.rubyonrails.org/performance_testing.html . Мои вопросы находятся в конце этой речи на тему «как я начал».

Итак, я начал с простого:

 class BrowsingTest < ActionDispatch::PerformanceTest
  self.profile_options = { :runs => 5, :metrics => [:wall_time, :process_time],
                       :output => 'tmp/performance', :formats => [:flat] }
  def test_homepage
    get '/'
  end
end
 

вывод

 bundle exec rake test:profile
 

в терминале есть

 BrowsingTest#test_homepage (909 ms warmup)
           wall_time: 341 ms
        process_time: 517 ms
 

и в плоском файле process_time все начинается так

 Thread ID: 70299857145540
Total: 2.589931

 %self     total     self     wait    child    calls  name
 12.45      0.32     0.32     0.00     0.00      110  BasicObject#method_missing
 10.59      0.28     0.27     0.00     0.01      415  Kernel#raise
  7.79      0.20     0.20     0.00     0.00     1350  <Class::Dir>#[]
 

Не совсем зная, что с этим делать, я начал с поиска чего-то, что часто использует method_missing . Я обнаружил, что библиотека, которую я использую для преобразования метрик (Alchemist), делает это и включает себя в Числовой класс.

Поскольку домашняя страница на самом деле в этом не нуждается, я просто удалил библиотеку и повторно запустил тест профилирования. На этот раз я получил следующее

 BrowsingTest#test_homepage (856 ms warmup)
           wall_time: 321 ms
        process_time: 482 ms
 

И в плоском файле больше не было method_missing

 Thread ID: 70185893711560
Total: 2.420023

 %self     total     self     wait    child    calls  name
 12.05      0.29     0.29     0.00     0.00        5  ActionView::Base#helpers
  8.32      0.20     0.20     0.00     0.00     1350  <Class::Dir>#[]
  5.12      0.12     0.12     0.00     0.00     5925  String#gsub
 

Я запустил его во второй раз и получил

 BrowsingTest#test_homepage (856 ms warmup)
           wall_time: 321 ms
        process_time: 482 ms

Thread ID: 70231460630220
Total: 2.411142

 %self     total     self     wait    child    calls  name
 14.18      1.49     0.34     0.00     1.16     3265  Array#each
  8.26      0.20     0.20     0.00     0.00     1350  <Class::Dir>#[]
  4.94      0.12     0.12     0.00     0.00      205  Kernel#caller
 

Таким образом, кажется, что отказ от использования библиотеки экономит время процесса ~ 35 мс, что, похоже, вполне согласуется с тем, что сказано в плоских файлах. Я думаю, мне следует попытаться что-то с этим сделать, тем более что, похоже, это так часто вызывается из-за числового включения.

Теперь вот мои вопросы:

  • Правильный ли это подход? Есть ли лучший способ начать?
  • Каков наилучший способ точно определить класс / метод, который снижает производительность (следующим шагом для меня было бы поискать что-то с помощью Dir , но есть несколько мест, где это используется)
  • Каково приемлемое время процесса?
  • Я запустил test:profile несколько раз подряд, и время self для «String#gsub» увеличилось с 0,04 до 0,12. Что может произойти?

Спасибо!

Ответ №1:

Мне нравится, как вы познакомились с инструментами и как читать результаты. New Relic — отличный инструмент для мониторинга этого материала, но также и request_log_analyzer, если вы не хотите платить за new relic в долгосрочной перспективе.

  1. используйте Yslow или Page speed для профилирования всей страницы, а не только загрузки html
  2. Оптимизируйте страницу и то, как она загружает / кэширует ресурсы
  3. Найдите свои самые медленные действия и выясните, что они делают (медленный код или медленный запрос?)
  4. Оптимизируйте запросы, добавляйте индексы там, где это необходимо, кэшируйте данные
  5. Удалите или обновите старые библиотеки
  6. Автономные дорогостоящие процессы (фоновые, задания cron и т. Д.)
  7. Настройте свою архитектуру (вам не нужны Rails для всего, переходите на jruby и используйте мощные библиотеки Java, потоки и время выполнения)

Мониторинг важен, поэтому вы знаете, когда возникает проблема

-Джон Маккаффри

Ответ №2:

Я действительно не считаю, что эти тесты производительности страницы необходимы. Я считаю важным только раннее развертывание и включение некоторой формы мониторинга приложений (например, new relic RPM). С его помощью вы можете определить все узкие места вашего приложения и исправить их со временем по мере роста приложения.