2012-01-04 3 views
1

私のモデルでシリアル化された配列フィールドを使用しています。具体的には、各配列のメンバー数を共有しています。Ruby Array - すばやくオーバーラップする方法

今、私のプロジェクトの性質上、これらの重複カウントが非常に多いため、これを行うにはすばやく簡単な方法があるのだろうかと思っていました。

瞬間、私のコードは正常に動作します。この

(user1.follower_names & user2.follower_names).count 

のように見えるので、私は、「&」メソッドを使用しています...しかし、私はそれを行うためのより高速な方法があるかもしれない期待していました。

+0

正確なRubyには当てはまりませんが、Pythonには組み込みタイプのSetがあります。あなたはすべてのフォロワーを追加して、その長さ/カウントをつかむことができます。誰かがルビー・ウェイを知っているかもしれませんし、どんなパフォーマンスが期待できるでしょうか。 –

答えて

4

これはより高速です。

require 'benchmark' 
require 'set' 
alphabet = ('a'..'z').to_a 
user1_followers = 100.times.map{ alphabet.sample(3) } 
user2_followers = 100.times.map{ alphabet.sample(3) } 
user1_followers_set = user1_followers.to_set 
user2_followers_set = user2_followers.to_set 

n = 1000 
Benchmark.bm(7) do |x| 
    x.report('arrays'){ n.times{ (user1_followers & user2_followers).size } } 
    x.report('set'){ n.times{ (user1_followers_set & user2_followers_set).size } } 
end 

出力:

   user  system  total  real 
arrays 0.910000 0.000000 0.910000 ( 0.926098) 
set  0.350000 0.000000 0.350000 ( 0.359571) 
+0

配列をセットにするのにかかる時間が少し心配です。それはごくわずかですか?私の配列の長さは0〜3000です。 – BananaNeil

+0

いいえ、無視できません。実際の交差操作と一緒に(1000回)設定するための両方の変換には、このアンティークラップトップで約1秒かかります。しかし、user_followerが複数のフォロワーと比較されるシナリオでは、セットを(メモリー内に)保管し、フォロワーの数が1より大きい場合に時間がかかるようになります。つまり、2回変換しないでください。 – steenslag

+0

ちょうどいくつかの数字を走らせました...そして、セットを使っているように見えるのは、セットへの変換だけが長くかかったためです。私はすべてのデータ構造をシリアル化されたセットに変更することができるかもしれないと思っています。その時点で、はるかに高速です。 – BananaNeil

1

上記の代わりに使用することです「 - 」配列にオペレータを:

user1.follower_names.size - (user1.follower_names - user2.follower_names).size 

基本的にこれはリスト1とマイナスのサイズを取得します交差点のない共同リストのサイズ。これはセットを使用するほど高速ではありませんが、配列との交差を単独で使用するよりもはるかに速い

+0

それは非常に速く(約1/100000秒)非常に判明しましたが、何回何回実行しても、少し速くなります。 – BananaNeil

関連する問題