2009-04-27 7 views
2

は、私はさておきdo_something_withが呼ばれる方法を変更するから、このルビーループリファクタリング

def slow_loop(array) 
array.each_with_index do |item, i| 
    next_item = array[i+1] 
    if next_item && item.attribute == next_item.attribute 
    do_something_with(next_item) 
    end 
end 
end 

のように見えるループを持って、どのように私は、これはパフォーマンスが向上することができますか?

THX、

-C

P.S.

これは 'O(n)'操作であるように見えるので、ここで得られるパフォーマンスはないと思われるので、私が選択した答えは、この操作を既にカプセル化しているrubyメソッドを使用するものです。みんな助けてくれてありがとう

+0

おそらく、あなたが持っている要素の数と、あなたが思いついたベンチマークの数字を教えてください。これはO(n)操作であるべきです(SHOULD)。 – Trey

+0

これは愚かに聞こえる場合は私を許してください、しかし、O(n)の操作は何ですか? –

+0

基本的には、操作の時間は要素の数に直接関係しますn –

答えて

6
他の人はあなたがはるかにパフォーマンスを改善するつもりはないが、あなたはそうのような、よりきれいにこれを行うことができます述べたように

array.each_cons(2) do |a, b| 
    do_something_with(b) if a == b 
end 
+0

はここで 'b'にする必要がありますか? –

+0

興味深い - 前にeach_consを見たことがありませんでした。 –

+0

@Chris Drappier:はい感謝 - ちょうどそれが気付いた – tgamblin

2

パフォーマンスはdo_something_withです。それ以外のものはミクロ最適化になります。

これはO(n)である必要があります。最後のチェックを避ける方法はありますが、それは物事の壮大な計画ではそれほどコストがかかることはありません。

+0

これが当てはまる場合は、私の唯一の他の質問は、このタイプのプロシージャを既にカプセル化しているルビメソッドがあることでしょうか? –

0

私は最適化の可能性にギャリーに同意する傾向があるが、それはすることができます確かにより簡単に書かれています。

prev_attr = nil 
my_array.each |item| 
    do_something_with(item) if prev_attr and prev_attr == item.attribute 
    prev_attr = item.attribute 
end