манипуляция большими массивами очень медленная в ruby

У меня следующий сценарий:

Мне нужно вычислить уникальный список идентификаторов в очень большом множестве.

Например, у меня есть 6000 массивов идентификаторов (список последователей), каждый из которых может иметь размер от 1 до 25000 (список их последователей).

Я хочу получить уникальный список идентификаторов во всех этих массивах идентификаторов (уникальные последователи последователей). После этого мне нужно вычесть другой список (список последователей другого человека) идентификаторов и получить окончательный подсчет.

Окончательный набор уникальных идентификаторов вырастает примерно до 60 000 000 записей. В Ruby при добавлении массивов к большому массиву он начинает работать очень медленно примерно после пары миллионов. Сначала добавление к набору занимает .1 секунду, затем увеличивается до более чем 4 секунд при 2 миллионах (это совсем не то, что мне нужно).

Я написал тестовую программу на java, и она выполняет все действия менее чем за минуту.

Возможно, я делаю это неэффективно в ruby, или есть другой способ. Поскольку мой основной код проприетарный, я написал простую тестовую программу, чтобы смоделировать проблему:

big_array = []
loop_counter = 0
start_time = Time.now
# final target size of the big array
while big_array.length < 60000000
 loop_counter+=1
 # target size of one persons follower list
 random_size_of_followers = rand(5000)
 follower_list = []
 follower_counter = 0
   while follower_counter < random_size_of_followers
     follower_counter+=1
     # make ids very large so we get good spread and only some amt of dupes
     follower_id = rand(240000000) + 100000
     follower_list << follower_id
   end
 # combine the big list with this list
 big_array = big_array | follower_list
 end_time = Time.now

 # every 100 iterations check where we are and how long each loop and combine takes.
 if loop_counter % 100 == 0
   elapsed_time = end_time - start_time
   average_time = elapsed_time.to_f/loop_counter.to_f
   puts "average time for loop is #{average_time}, total size of big_array is #{big_array.length}"
   start_time = Time.now
 end
end

Есть предложения, пора ли переходить на jruby и переносить подобные вещи в java?

8
задан Eric Hu 22 April 2013 в 01:10
поделиться