Skip to content

Instantly share code, notes, and snippets.

@JoelHough
Created April 30, 2014 16:57
Show Gist options
  • Save JoelHough/6ff9bcfbb85bef031c18 to your computer and use it in GitHub Desktop.
Save JoelHough/6ff9bcfbb85bef031c18 to your computer and use it in GitHub Desktop.
calls = Hash.new(0)
stack = []
trace_file = ARGV[0]
times = Hash.new([])
positions = Hash.new([])
lines = []
File.open(trace_file, 'r') {|f|
lines = f.readlines
}
rb = "["
lines.each {|line|
event, id, klass, self_class, file, line_num, time, extra_data = eval(line)
next if file.include? "/vendor/bundle/gems"
next if file.include? "/.rbenv/"
next if file.include? '"'
name = klass + '::' + id.to_s
if event == 'return'
if line == lines[-1] && stack.length > 1
while stack.length > 1
n, t = stack.pop
rb << "], :end => #{time.to_i}, :duration => #{time.to_i - t}},\n"
end
end
if stack[-1][0] == name
times[name] += [[stack[-1][1], time.to_i]]
rb << "], :end => #{time.to_i}, :duration => #{time.to_i - stack[-1][1]}},\n"
stack.pop
end
elsif event == 'call'
positions[name] = [file, line_num]
calls[[stack[-1][0], name]] += 1 unless stack.empty?
stack.push [name, time.to_i]
is_class_method = !self_class || ['Class', 'Module'].include?(self_class)
display_name = (is_class_method ? klass + '::self.' : self_class + '::') + id.to_s
rb << "{:name => \"#{display_name + (extra_data ? ' ' + extra_data.inspect : '')}\", :file => \"#{file}\", :line => #{line_num}, :start => #{time.to_i}, :children => ["
end
}
rb << "]"
tree = eval(rb)
def compute_self_durations(tree)
tree.each do |call|
call[:self_duration] = call[:duration] - call[:children].collect{|c| c[:duration]}.inject(0, :+)
compute_self_durations(call[:children])
end
end
compute_self_durations(tree)
puts "events: ns\n\n"
def tree_print_callgrind_calls(tree)
tree.each do |call|
puts "fl=#{call[:file]}\nfn=#{call[:name]}\n#{call[:line]} #{call[:self_duration]}\n"
call[:children].each do |child|
puts "cfl=#{child[:file]}\ncfn=#{child[:name]}\ncalls=1 #{child[:line]}\n#{call[:line]} #{child[:duration]}\n"
end
puts "\n"
tree_print_callgrind_calls(call[:children])
end
end
tree_print_callgrind_calls(tree)
exit(0)
def insignificant?(name,times)
sum = 0
times[name].each {|t| sum += t[1] - t[0]}
return true if sum == 0
avg = sum / times[name].length
avg < 1000
end
def duration(times)
times[1] - times[0]
end
keys = []
calls.each do |k,v|
keys += k
end
keys.uniq!
keys.each do |name|
puts "fl=#{positions[name][0]}\nfn=#{name}\n"
times[name].each do |t|
puts "#{positions[name][1]} #{duration(t)}\n"
end
puts "\n"
end
return
puts "digraph G {"
keys.each do |key|
puts " \"#{key}\";\n"
end
calls.each do |k,v|
puts " \"%s\" -> \"%s\" [ label=\"%i calls\" ];\n" % [k[0], k[1], v]
end
puts "}\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment