Как добавить / изменить / консолидировать данные J Ruby Profiler? - PullRequest
0 голосов
/ 16 апреля 2020

Скажем, у меня внутри моей программы J Ruby следующее l oop:

loop do
  x=foo()
  break if x
  bar()
end

, и я хочу собрать информацию о профилировании только для вызовов bar. Как это сделать? Я так далеко:

pd = []
loop do
  x=foo()
  break if x
  pd << JRuby::Profiler.profile { bar() }
end

Это оставляет мне массив pd объектов данных профиля, по одному на каждый вызов bar. Есть ли способ создать «сводный» объект данных, комбинируя все элементы pd? Или, что еще лучше, иметь один объект, куда profile просто добавит существующую информацию о профилировании?

Я погуглил документацию по API J Ruby :: Profiler, но не смог найти ничего, кроме нескольких простых примеров, ни один из которых не охватывал мой случай.

ОБНОВЛЕНИЕ : Вот еще одна попытка, которую я попробовал, но она тоже не работает.

Поскольку метод profile первоначально очищает данные профиля внутри Profiler, я попытался отделить этапы профилирования от инициализации данных. шаги, подобные этому:

JRuby::Profiler.clear
loop do
  x=foo()
  break if x
  JRuby::Profiler.send(:current_thread_context).start_profiling
  bar()
  JRuby::Profiler.send(:current_thread_context).stop_profiling
end
profile_data = JRuby::Profiler.send(:profile_data)

Сначала это работает, но после исследования я обнаружил, что profile_data содержит информацию о профилировании из последнего (самого последнего) выполнения bar, а не всех казней, собранных вместе.

1 Ответ

0 голосов
/ 16 апреля 2020

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

Проблема с профилированием заключается в том, что start_profiling (соответствует Java метод startProfiling в классе Java :: OrgJrubyRuntime :: ThreadContext) не только включает флаг профилирования, но также выделяет объект fre sh ProfileData. Что мы хотим сделать, это повторно использовать старый объект. stop_profiling OTOH только включает переключатель профилирования и некритичен.

К сожалению, ThreadContext не предоставляет метод для управления переключателем isProfiling, поэтому в качестве первого шага мы должны добавить один:

class Java::OrgJrubyRuntime::ThreadContext
  field_writer :isProfiling 
end

С этим мы можем установить / сбросить внутренний переключатель isProfiling. Теперь мой l oop становится:

context = JRuby::Profiler.send(:current_thread_context)
JRuby::Profiler.clear
profile_data_is_allocated = nil
loop do
  x=foo()
  break if x
  # The first time, we allocate the profile data
  profile_data_is_allocated  ||= context.start_profiling
  context.isProfiling = true
  bar()
  context.isProfiling = false
end
profile_data = JRuby::Profiler.send(:profile_data)

. В этом решении я старался максимально приблизиться к возможностям класса JRuby::Profiler, но мы видим, что единственная публика c метод все еще используется метод clear. По сути, я переопределил профилирование в терминах класса ThreadContext; поэтому, если кто-то придумает лучший способ ее решить, я буду очень признателен.

...