Профилирование Ruby Code - PullRequest
       16

Профилирование Ruby Code

27 голосов
/ 04 ноября 2010

Помимо ruby-prof и базового класса Benchmark, что вы используете для профилирования вашего кода Ruby?В частности, как вы находите узкие места в вашем коде?Мне почти кажется, что мне нужно поработать над своим собственным небольшим инструментом, чтобы выяснить, на что тратится все время в моем коде.

Я понимаю, что ruby-prof предоставляет это, но результат, откровенно говоря, очень запутанныйне позволяет легко определить, какие именно блоки вашего собственного кода являются источником проблемы (хотя и говорит о том, какие вызовы методов заняли больше всего времени).Так что я на самом деле не получаю от этого столько, сколько хотел бы, и на самом деле не смог использовать это.

Возможно, я делаю это неправильно?Есть ли альтернативы?Поиски в Google ничего мне не дают.

Ответы [ 4 ]

9 голосов
/ 29 июня 2015

Чтобы действительно углубиться в ваш код, попробуйте stackprof .

Вот краткое решение о том, как его использовать: Установите gem: gem install stackprof.В вашем коде добавьте: require 'stackprof' и окружите часть, которую вы хотите проверить, следующим образом:

StackProf.run(mode: :cpu, out: 'stackprof-output.dump') do {YOUR_CODE} end

После запуска вашего сценария ruby ​​проверьте вывод в терминале с помощью stackprof stackprof.dump:

Mode: cpu(1000)
Samples: 9145 (1.25% miss rate)
GC: 448 (4.90%)

 TOTAL    (pct)     SAMPLES    (pct)     FRAME
   236   (2.6%)         231   (2.5%)     String#blank?
   546   (6.0%)         216   (2.4%)     ActiveRecord::ConnectionAdapters::Mysql2Adapter#select
   212   (2.3%)         199   (2.2%)     Mysql2::Client#query_with_timing
   190   (2.1%)         155   (1.7%)     ERB::Util#html_escape``

Здесь вы можете увидеть все ваши методы, которые требуют много времени.Теперь классная часть: для детализации просто выполните stackprof stackprof.dump --method String#blank?, и вы получите вывод для конкретного метода:

String#blank? (lib/active_support/core_ext/object/blank.rb:80)
  samples:   231 self (2.5%)  /    236 total (2.6%)
  callers:
    112  (   47.5%)  Object#present?
  code:
                                  |    80  |   def blank?
  187    (2.0%) /   187   (2.0%)  |    81  |     self !~ /[^[:space:]]/
                                  |    82  |   end

И вы можете довольно легко определить, какая часть вашего кода занимает много времени дляrun.

Если вы хотите получить визуальный вывод, выполните stackprof stackprof.dump --graphviz >> stackprof.dot и с помощью graphviz (brew install graphviz) dot -T pdf -o stackprof.pdf stackprof.dot получите прекрасный вывод PDF, в котором выделены методы, выполнение которых занимает много времени.

6 голосов
/ 04 ноября 2010

Многие профилировщики такие. Вам нужно знать не , где программа тратит свое время, а , почему . Есть ли ссылки на динамический анализ кода?

ДОБАВЛЕНО: Вот как Я нахожу "узкие места" в своем коде. (Я ненавижу это слово.) Вот список причин, по которым.

Вполне естественно предположить, что для того, чтобы найти «узкие места», нужно как-то много измерять. Это настолько естественно, что почти все профилировщики основаны на нем.

На самом деле поиск и измерение - это не одна и та же проблема. Измерение необходимо, чтобы увидеть, если то, что вы нашли (и исправили), изменило ситуацию. Для меня поиск того, что исправить, больше похоже на отладку, чем на измерение.

Простейший способ объяснить это - начать с бесконечного или почти бесконечного цикла. Как вы это нашли? Вы делаете паузу и смотрите на стек, верно? потому что вы знаете, проблема где-то в стеке. Вам нужно только сделать паузу один раз, а затем вам нужно изучить код в стеке. Сделайте паузу несколько раз, если хотите быть уверенным, что нашли это.

Предположим, что код занимает только вдвое больше времени, чем необходимо. Это означает, что когда вы делаете паузу, есть 50% шанс, что вы увидите, что он делает ненужные вещи. Если вы сделаете паузу и посмотрите на нее 10 раз, вы поймаете это примерно 5 раз. Фактически, как только вы заметите, что он делает что-то, что вы можете оптимизировать всего за 2 сэмпла, вы обнаружите «узкое место». Исправьте это, измерьте ускорение, покажите его и повторите.

Даже если ваша самая большая проблема не очень большая, этот метод в конечном итоге найдет ее. Кроме того, существует явление увеличения, при котором небольшие проблемы легче найти после удаления более крупных. Это позволяет продолжать работу до тех пор, пока код не станет почти оптимальным.

P.S. После того, как вы это сделаете, все еще могут быть возможности для ускорения. Например, алгоритмы оптимизации могут зависеть от численной устойчивости. Управляемые сообщениями архитектуры могут усложнить отслеживание того, почему выполняется код. В программном обеспечении реального времени проблемы с производительностью могут возникать лишь изредка, и их проще отобрать. Это требует большей сообразительности. Откат на измерения просто не делает этого.

3 голосов
/ 25 января 2014

Это мой собственный вопрос, но я нашел инструмент, который настолько хорош для профилирования, что мне нужно добавить его здесь:

http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-miniprofiler

Flamegraphs делает источник проблем производительности удивительным очевидно относительно просмотра следов.

2 голосов
/ 12 июля 2017

Существует также ruby -rprofile или, что эквивалентно, из источника Ruby, require 'profile'

Документация:

https://ruby -doc.org / STDLIB-2.1.0 / libdoc / профайлер / RDoc / Profiler __. HTML

...