Skip to content

Instantly share code, notes, and snippets.

@nandilugio
Last active August 29, 2015 13:56
Show Gist options
  • Save nandilugio/8934957 to your computer and use it in GitHub Desktop.
Save nandilugio/8934957 to your computer and use it in GitHub Desktop.
require 'active_support/core_ext/module'
require 'active_support/core_ext/benchmark'
Object.singleton_class.class_eval do
def profile_methods(*names)
names.each do |name|
case name
when Regexp
profiling_methods.grep(name).each { |match| profile_method(match) }
else
_profile_method(name)
end
end
end
def profile_methods!
profiling_methods.each { |method| profile_method(method) }
end
def profiling_methods
methods = self.instance_methods(false)
methods.delete(:initialize)
methods
end
alias_method :profile_method, :profile_methods
private
def _profile_method(method_name)
method_name_with_profiling, method_name_without_profiling = build_profiling_method_names(method_name)
unless method_defined?(method_name_with_profiling)
define_method method_name_with_profiling do |*args, &block|
value = nil
time = Benchmark.ms { value = send(method_name_without_profiling, *args, &block) }
arg_values = args.inspect
arg_values = arg_values[/^\[(.+)\]$/, 1] || ""
arg_values = arg_values.size > 180 ? [arg_values[0..180], "..."].join : arg_values
!arg_values == "" && arg_values = ["(", arg_values, ")"].join
puts "(%010.2fms) #{self.class}##{method_name}#{arg_values}" % [time]
value
end
alias_method_chain method_name, :profiling
end
end
def build_profiling_method_names(target)
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
[:"#{aliased_target}_with_profiling#{punctuation}", :"#{aliased_target}_without_profiling#{punctuation}"]
end
end
Module.class_eval do
def profile_methods!
local_constants.each do |constant|
klass = const_get(constant)
if klass.respond_to?(:profiling_methods)
klass.profiling_methods.each { |method| klass.profile_method(method) }
end
end
end
end
(0000000.00ms) Namespace::Awesome#i_am
(0000000.01ms) Greeter#say_hello
Hello!
require_relative 'method_profiling'
class Greeter
def say_hello
puts "Hello!"
end
def say_yeah
puts "Yeah!"
end
end
module Namespace
class Awesome
def i_am
end
end
end
Greeter.profile_methods /^say_/
Namespace.profile_methods!
Greeter.new.say_hello
Namespace::Awesome.new.i_am
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment