Ruby Array - быстрый способ пересчета - PullRequest
1 голос
/ 04 января 2012

Я работаю с сериализованными полями массива в одной из моих моделей, в частности, для подсчета общего числа членов каждого массива.

Теперь, в силу характера моего проекта, у меня ОГРОМНОЕ числоиз этих подсчетов перекрытий ... поэтому мне было интересно, есть ли супер быстрый, умный способ сделать это.

В настоящее время я использую метод '&', поэтому мой код выглядит так

(user1.follower_names & user2.follower_names).count

, который работает нормально ... но я надеялся, что может быть более быстрый способ сделать это.

Ответы [ 2 ]

4 голосов
/ 04 января 2012

Наборы для этого быстрее.

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)
1 голос
/ 04 января 2012

Альтернативой вышеупомянутому является использование оператора '-' для массивов:

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

По существу это позволяет получить размер первого списка и минус размер объединенного списка без пересечения.Это не так быстро, как использование множеств, но гораздо быстрее, чем использование пересечения с массивами

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...