我有很多混乱的代码,涉及包装基准来执行块中的许多单个方法,记录它们执行的时间,然后将这些信息发送到数据库中供以后参考。这使得代码非常难看。
benchmark_data = Benchmark.realtime do
begin
do_something()
rescue StandardError => e
log_errors("error occurred")
raise e
end
end
write_benchmark_data_to_db(benchmark_data)
此代码基本上复制了我们想要基准测试的每个函数。使用元编程有更好的方法吗?我希望将所有基准测试代码保留在我测量方法的类中。
我在想
class Foo
def a()
puts "A"
end
... #repeat for b,c,d,e...
end
f = Foo.new()
add_benchmark(f, [:a,:b,:d]) #records a benchmark event each time f.a,f.b, and f.d are called
有没有人有任何想法?如果可能的话,我想避免使用Foo的子类,因为每个需要基准测试的对象都需要一个子类。
答案 0 :(得分:0)
这是一个惯用的Ruby解决方案:
def with_stored_benchmark(&block)
benchmark_data = Benchmark.realtime do
begin
block.call
rescue StandardError => e
log_errors("error occurred")
raise e
end
end
write_benchmark_data_to_db(benchmark_data)
end
这是另一种解决方案(种类):
class Module
def method_bmark_database(*syms)
syms.each do |sym|
old=instance_method(sym)
define_method(sym) do |*args|
benchmark_data = Benchmark.realtime do
begin
old.call(*args)
rescue StandardError => e
log_errors("error occurred")
raise e
end
end
write_benchmark_data_to_db(benchmark_data)
end
end
end
end
这个猴子补丁Module
,但你总是把它放在一个模块中并包含它。我不确定它是否有效,因为我现在不在使用Ruby的计算机,但它看起来对我来说。
此外,如果您想选择哪些对象进行基准测试:
def log_performance_to_DB(obj, *methods)
methods.each do |m|
old=obj.method(m)
obj.define_singleton_method(m) do |*args|
benchmark_data = Benchmark.realtime do
begin
old.call(*args)
rescue StandardError => e
log_errors("error occurred")
raise e
end
end
write_benchmark_data_to_db(benchmark_data)
end
end
end
答案 1 :(得分:0)
为什么不做
之类的事情class Object
alias :old_method_missing :method_missing
def method_missing( meth, *args, &block )
if benchmark_method? meth
begin
old_method_missing meth, *args, &block
rescue Exception => e
log_errors( "..." )
raise e
end
else old_method_missing meth, *args, &block
end
end
end
我认为这是不言自明的。也许我不明白你的意思,......