2015-01-06 137 views
2

我必須從不同的來源查詢一組模型對象。每個源都會返回一個帶哈希像的對象的數組,但同一模型的佈局(LogDoc)並不相同。紅寶石陣列適配器

我的第一種方法是將查詢結果對象包裝到一個數組適配器中,該適配器基本上轉換了每個提取的元素,每個元素都在#每個塊中。這是我想出了:

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是低效

是否可以使用收益率?還是性能影響真的值得考慮?

回答

3

您可以只需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 
+0

,你可以發表主旨你如何做基準? – SystematicFrank

+0

@SystematicFrank請參閱https://gist.github.com/jiripospisil/0774b7767d252d871992。你可能會得到更高的數字,因爲我在一臺相當老的筆記本電腦上運行這個數字。 –

+1

謝謝!良好的分析技能是一個往往被大大低估的金礦 – SystematicFrank