私はさまざまな最適化手法を調査していて、この投稿に出くわしました コードを効率的に分析していますか? コールスタックのサンプリングがプロファイラーを使用するよりも効果的であると信じている人によって。基本的な考え方は、コールスタックを表示すると、アプリケーションがほとんどの時間を費やす可能性が最も高い場所を確認し、そこで最適化することです。
それは確かに興味深いものであり、彼は明らかにこれに関する専門家ですが、Rubyでコールスタックを表示する方法がわかりません。デバッガでは「情報スタック」と言うことができますが、1行しか表示されないようです。
編集:私はマイクダンレービーのこのコメントを見ました:「デバッガーの下で実行する場合、手動で中断して、コールスタックを表示することを指摘したい...」
手動で中断してコールスタックをディップレイする方法がわかりません。
置くだけ
puts caller
コードのどこでも。形式が気に入らない場合は、文字列の配列なので、目的の出力に対して正規表現を操作できます。
Rubyプロセスにシグナルを送信し、すべてのスタックをダンプするシグナルのハンドラーを作成するのはどうですか?
http://le-huy.blogspot.com/2012/04/dump-backtrace-of-all-threads-in-Ruby.html から、次の例があります。
require 'pp'
def backtrace_for_all_threads(signame)
File.open("/tmp/Ruby_backtrace_#{Process.pid}.txt","a") do |f|
f.puts "--- got signal #{signame}, dump backtrace for all threads at #{Time.now}"
if Thread.current.respond_to?(:backtrace)
Thread.list.each do |t|
f.puts t.inspect
PP.pp(t.backtrace.delete_if {|frame| frame =~ /^#{File.expand_path(__FILE__)}/},
f) # remove frames resulting from calling this method
end
else
PP.pp(caller.delete_if {|frame| frame =~ /^#{File.expand_path(__FILE__)}/},
f) # remove frames resulting from calling this method
end
end
end
Signal.trap(29) do
backtrace_for_all_threads("INFO")
end
次に、適切なプロセスに信号を送信する必要があります。
ps afxw | grep Ruby
kill -29 <pid>
ls -l /tmp/Ruby*
vi /tmp/Ruby_backtrace_...
適切なサンプリング時間で信号を繰り返します。
いつでも例外をスローしてから、$@
事前定義変数。バックトレースデータの配列を返します。例えば。これをfoo.rbに入れます:
begin
raise 'foo'
rescue
puts $@
end
次にそれを実行します:
$ Ruby foo.rb
foo.rb:2:in `<main>'