Ruby 数组适配器
Ruby array adapter
我必须查询一组来自不同来源的模型对象。每个来源returns一个Array with Hash like objects,但是同一模型(LogDoc)的布局不一样。
我的第一个方法是将查询结果对象包装到一个数组适配器中,该适配器基本上转换 #each 块中提取的每个元素。这是我想到的:
class MongoQueryAdapter
extend Forwardable
def initialize(mongo_query)
@query_rows = mongo_query
...
end
def_delegators :@query_rows, ...
def each(&block)
@query_rows.each do |raw|
log = LogDoc.new raw
block.call(log)
end
end
end
这是我认为更适合我的用例的模式,但我担心性能,因为我听说 block.call 与 产量.
是否可以使用 yield 来实现?或者性能影响真的值得考虑吗?
您可以 yield
而不是调用块,不需要其他更改。
def each
if block_given?
@query_rows.each do |raw|
yield LogDoc.new(raw)
end
else
# return Enumerator or raise
end
end
看代码,我觉得你其实可以稍微简化一下:
def each(&block)
@query_rows.map { |raw| LogDoc.new(raw) }.each(&block)
end
是的,yield
往往要快得多:
Calculating -------------------------------------
bench_block 30.600k i/100ms
bench_yield 42.073k i/100ms
-------------------------------------------------
bench_block 768.311k (± 6.0%) i/s - 3.825M
bench_yield 3.917M (± 2.8%) i/s - 19.564M
我必须查询一组来自不同来源的模型对象。每个来源returns一个Array with Hash like objects,但是同一模型(LogDoc)的布局不一样。
我的第一个方法是将查询结果对象包装到一个数组适配器中,该适配器基本上转换 #each 块中提取的每个元素。这是我想到的:
class MongoQueryAdapter
extend Forwardable
def initialize(mongo_query)
@query_rows = mongo_query
...
end
def_delegators :@query_rows, ...
def each(&block)
@query_rows.each do |raw|
log = LogDoc.new raw
block.call(log)
end
end
end
这是我认为更适合我的用例的模式,但我担心性能,因为我听说 block.call 与 产量.
是否可以使用 yield 来实现?或者性能影响真的值得考虑吗?
您可以 yield
而不是调用块,不需要其他更改。
def each
if block_given?
@query_rows.each do |raw|
yield LogDoc.new(raw)
end
else
# return Enumerator or raise
end
end
看代码,我觉得你其实可以稍微简化一下:
def each(&block)
@query_rows.map { |raw| LogDoc.new(raw) }.each(&block)
end
是的,yield
往往要快得多:
Calculating -------------------------------------
bench_block 30.600k i/100ms
bench_yield 42.073k i/100ms
-------------------------------------------------
bench_block 768.311k (± 6.0%) i/s - 3.825M
bench_yield 3.917M (± 2.8%) i/s - 19.564M