33 votes

Profil d'une action de contrôleur rails

Quelle est la meilleure façon de profiler une action de contrôleur en Ruby on Rails. Actuellement, j'utilise la méthode brute qui consiste à ajouter des appels puts Time.now entre ce que je pense être un goulot d'étranglement. Mais cela me semble vraiment, vraiment sale. Il doit y avoir une meilleure façon.

44voto

Rob Davis Points 7639

J'ai appris cette technique il y a un moment et je l'ai trouvée très pratique.

Quand elle est en place, vous pouvez ajouter ?profile=true à n'importe quelle URL qui atteint un contrôleur. Votre action s'exécutera comme d'habitude, mais au lieu de livrer la page rendue au navigateur, elle enverra une page ruby-prof détaillée et joliment formatée qui montre où votre action a passé son temps.

Tout d'abord, ajoutez ruby-prof à votre Gemfile, probablement dans le groupe de développement :

group :development do
    gem "ruby-prof"
end

Ensuite, ajoutez un filtre autour à votre ApplicationController :

around_action :performance_profile if Rails.env == 'development'

def performance_profile
  if params[:profile] && result = RubyProf.profile { yield }

    out = StringIO.new
    RubyProf::GraphHtmlPrinter.new(result).print out, :min_percent => 0
    self.response_body = out.string

  else
    yield
  end

Lire la sortie de ruby-prof est un peu un art, mais je vous laisse cela comme exercice.

Note supplémentaire de ScottJShea: Si vous voulez changer le type de mesure, placez ceci :

RubyProf.measure_mode = RubyProf::GC_TIME #exemple

Avant le if dans la méthode de profil de l'application controller. Vous pouvez trouver une liste des mesures disponibles sur la page ruby-prof. À la date de rédaction de cet article, les flux de données memory et allocations semblent être corrompus (voir défaut).

5 votes

Pour toute personne copiant-collant cela, vous devez également ajouter "require 'ruby-prof'" en haut de votre ApplicationController. De plus, pour moi, j'ai dû modifier "self.response_body=" en "self.response.body=" (Rails 2.3.14)

0 votes

Merci pour ces ajustements. response_body a été ajouté dans Rails 3.0. Et si vous utilisez Bundler, vous ne devriez pas avoir besoin de requérir ruby-prof, mais je suis content que cette technique ait été assez adaptable à une version plus ancienne de Rails.

0 votes

Merci pour le conseil, Pavling. J'utilise également Rails 2.3.14 et j'ai du mal à faire fonctionner cela. J'obtiens "wrong number of arguments (0 for 1)" dans graph_html_printer.rb:98:in `full_name', peu importe la version de ruby-prof que j'installe. Avez-vous une idée de ce qui pourrait causer cela ?

9voto

Stuart Points 173

Il y a un Railscast sur le profilage qui vaut la peine d'être visionné

http://railscasts.com/episodes/98-request-profiling

9voto

Chris Bunch Points 25857

Utilisez la bibliothèque standard Benchmark et les différents tests disponibles dans Rails (unité, fonctionnel, intégration). Voici un exemple :

def test_do_something
  elapsed_time = Benchmark.realtime do
    100.downto(1) do |index|
      # faire quelque chose ici
    end
  end
  assert elapsed_time < SOME_LIMIT
end

Voici, nous faisons simplement quelque chose 100 fois, mesurons le temps via la bibliothèque Benchmark, et nous nous assurons que cela a pris moins de temps que SOME_LIMIT.

Vous trouverez également ces liens utiles : La référence Benchmark.realtime et la référence Test::Unit. De plus, si vous êtes amateur de lectures, j'ai trouvé l'idée de l'exemple dans Agile Web Development with Rails, qui parle des différents types de tests et un peu des tests de performance.

3 votes

Cette réponse vous indique comment vous assurer que votre action s'exécute suffisamment rapidement. Cela ne vous aide pas dans le profilage, qui consiste à savoir quelle partie de l'action prend le plus de temps.

1voto

John Topley Points 58789

Vous voudrez peut-être essayer le service FiveRuns TuneUp, car il est vraiment plutôt impressionnant. Avis de non-responsabilité: Je ne suis associé d'aucune manière à FiveRuns, j'ai simplement essayé ce service.

TuneUp est un service gratuit où vous téléchargez un plugin et lorsque vous exécutez votre application, il injecte un panneau en haut de l'écran qui peut être étendu pour afficher des métriques de performance détaillées.

Il vous offre de jolis graphiques, y compris un qui montre quelle proportion de temps est passée dans le Modèle, la Vue et le Contrôleur. Vous pouvez même descendre jusqu'à voir les requêtes SQL individuelles qu'ActiveRecord exécute si nécessaire et il peut vous montrer le schéma de la base de données sous-jacente en un seul clic.

Enfin, vous pouvez optionnellement télécharger vos données de profilage sur le site de FiveRuns pour une analyse de performance communautaire et des conseils.

4 votes

Le lien est brisé (DNS expiré).

-1voto

P.S.V.R Points 564

Cela fonctionne dans Rails 4.2.6:

    o=OpenStruct.new(logger: Rails.logger)
    o.extend ActiveSupport::Benchmarkable
    o.benchmark 'nom' do
      # ... votre code ...
    end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X