问题描述
我编写了一个小的基准测试类来测试我的代码进行开发.目前我必须将 Class 添加到每个方法的开头和结尾.是否可以预先添加、即时附加,这样我就不必弄乱我的代码?
I wrote a small benchmarking Class for testing my code doing development. At the moment I have to add the Class to the beginning and end of every method. Is it posible to prepend, append on the fly, so that I don't have to clutter my code?
class ApplicationController
before_filter :init_perf
after_filter :write_perf_results_to_log!
def init_perf
@perf ||= Perf.new
end
def write_perf_results_to_log!
@perf.results
end
end
class Products < ApplicationsController
def foo
@perf.log(__methond__.to_s)
caculation = 5 *4
@perf.write!
end
def bar
@perf.log(__methond__.to_s)
caculation = 1 / 5
@perf.write!
end
end
这是 Perf 类.它位于服务文件夹中.
This is the Perf class. It is located in the services folder.
class Perf
def initialize
@results = []
end
def log(note)
@start = Time.now
@note = note
end
def write!
if @results.find {|h| h[:note] == @note } # Update :sec method exists in results
@results.select { |h| h["note"] == @note; h[":sec"] = (Time.now - @start).round(3) }
else # Add new Hash to results
@results << { :note => @note, :sec => (Time.now - @start).round(3) }
end
end
def results
content = "
PERFORMANCE STATISTICS!
"
@results.each do |r|
content += r[:note] + " " + r[:sec].to_s + "
"
end
content += "
"
Rails.logger.info content
end
end
推荐答案
在一般的计算术语中,您想要执行的操作称为 代码检测.有几种方法可以实现这一点,但这里有一个使用元编程的(粗略)示例:
In general computing terms what you want to do is called code instrumentation. There are several ways to accomplish this, however here's one (crude) example using some metaprogramming:
首先定义一个我们将用于注入检测代码的新方法:
First define a new method that we will use for injecting our instrumentation code:
class ApplicationController
def self.instrument_methods(*methods)
methods.each { |m|
# Rename original method
self.send(:alias_method, "#{m}_orig", m)
# Redefine old method with instrumentation code added
define_method m do
puts "Perf log #{m}"
self.send "#{m}_orig"
puts "Perf write"
end
}
end
end
使用方法:
class Product < ApplicationController
def foo
puts "Foo"
end
def bar
puts "Bar"
end
# This has to be called last, once the original methods are defined
instrument_methods :foo, :bar
end
那么:
p = Product.new
p.foo
p.bar
将输出:
Perf log foo
Foo
Perf write
Perf log bar
Bar
Perf write
以下是检测 ruby 代码和衡量性能的其他一些方法:
Here are some other ways to instrument ruby code and measure performance:
http://ruby-prof.rubyforge.org/
http://www.igvita.com/2009/06/13/profiling-ruby-with-googles-perftools/
这篇关于Ruby/Rails:将代码添加到所有方法中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!