Skip to content

Instantly share code, notes, and snippets.

@tiegz
Created July 26, 2012 21:37
Show Gist options
  • Save tiegz/3184710 to your computer and use it in GitHub Desktop.
Save tiegz/3184710 to your computer and use it in GitHub Desktop.
Trying to implement a pure-ruby version of Memprof
puts "Experiment... don't use this on a big chunk of code."
if RUBY_VERSION != "1.9.3"
throw "This has only been tested on Ruby 1.9.3"
end
require 'stringio'
require 'pp'
class Tracer
def self.track
@@io, last_line, last_count = StringIO.new, 1, ObjectSpace.count_objects
set_trace_func proc { |event, file, line, id, binding, classname|
new_count = ObjectSpace.count_objects
if classname != "Tracer" && last_line > 1 # don't count the first trace_func
@@io.puts "#{file}:#{last_line}:TOTAL:#{(last_count[:TOTAL] - new_count[:TOTAL])}\n"
@@io.puts "#{file}:#{last_line}:T_OBJECT:#{new_count[:T_OBJECT] - last_count[:T_OBJECT]}\n"
@@io.puts "#{file}:#{last_line}:T_CLASS:#{new_count[:T_CLASS] - last_count[:T_CLASS]}\n"
@@io.puts "#{file}:#{last_line}:T_MODULE:#{new_count[:T_MODULE] - last_count[:T_MODULE]}\n"
@@io.puts "#{file}:#{last_line}:T_FLOAT:#{(new_count[:T_FLOAT] - last_count[:T_FLOAT])}\n"
@@io.puts "#{file}:#{last_line}:T_STRING:#{new_count[:T_STRING] - last_count[:T_STRING] - 131}\n"
@@io.puts "#{file}:#{last_line}:T_REGEXP:#{new_count[:T_REGEXP] - last_count[:T_REGEXP]}\n"
@@io.puts "#{file}:#{last_line}:T_ARRAY:#{new_count[:T_ARRAY] - last_count[:T_ARRAY] - 1}\n"
@@io.puts "#{file}:#{last_line}:T_HASH:#{new_count[:T_HASH] - last_count[:T_HASH] - 1}\n"
@@io.puts "#{file}:#{last_line}:T_BIGNUM:#{new_count[:T_BIGNUM] - last_count[:T_BIGNUM]}\n"
@@io.puts "#{file}:#{last_line}:T_FILE:#{new_count[:T_FILE] - last_count[:T_FILE]}\n"
@@io.puts "#{file}:#{last_line}:T_DATA:#{new_count[:T_DATA] - last_count[:T_DATA] - 1}\n"
@@io.puts "#{file}:#{last_line}:T_MATCH:#{new_count[:T_MATCH] - last_count[:T_MATCH]}\n"
@@io.puts "#{file}:#{last_line}:T_COMPLEX:#{new_count[:T_COMPLEX] - last_count[:T_COMPLEX]}\n"
@@io.puts "#{file}:#{last_line}:T_NODE:#{new_count[:T_NODE] - last_count[:T_NODE]}\n"
@@io.puts "#{file}:#{last_line}:T_ICLASS:#{new_count[:T_ICLASS] - last_count[:T_ICLASS]}\n"
end
last_line, last_count = line, new_count
}
yield
set_trace_func nil
@@io.rewind
# Fin
@@io.read.lines.each_with_object(Hash.new(0)) do |line, obj|
file, line, type, count = *line.strip.split(":")
count = count.to_i
obj["#{file}:#{line}:#{type}"] += count if count > 0
end
end
end
results = Tracer.track do
3.to_f
1000.times { "this is a string" }
class A; end
{:a => 1}
end
pp results
@tiegz
Copy link
Author

tiegz commented Jul 26, 2012

$ time ruby tracer.rb
Experiment... don't use this on a big chunk of code.
{"set_trace_func.rb:35:T_STRING"=>-128,
"set_trace_func.rb:36:T_DATA"=>1,
"set_trace_func.rb:49:T_FLOAT"=>1,
"set_trace_func.rb:50:T_DATA"=>1000,
"set_trace_func.rb:50:T_STRING"=>1000,
"set_trace_func.rb:51:T_CLASS"=>2,
"set_trace_func.rb:51:T_DATA"=>1,
"set_trace_func.rb:51:T_NODE"=>1,
"set_trace_func.rb:52:T_HASH"=>1}

real 0m21.524s
user 0m4.456s
sys 0m0.115s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment