Метод, который вы здесь используете, ужасно неэффективен, поэтому неудивительно, что он медленный.Когда вы пытаетесь отслеживать уникальные вещи, для массива требуется намного больше обработки, чем для хеш-эквивалента.
Вот простой рефакторинг, который увеличивает скорость примерно в 100 раз:
all_followers = { }
loop_counter = 0
start_time = Time.now
while (all_followers.length < 60000000)
# target size of one persons follower list
follower_list = []
rand(5000).times do
follower_id = rand(240000000) + 100000
follower_list << follower_id
all_followers[follower_id] = true
end
end_time = Time.now
# every 100 iterations check where we are and how long each loop and combine takes.
loop_counter += 1
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 all_followers is #{all_followers.length}"
start_time = Time.now
end
end
Хорошая вещь в хэше состоит в том, что невозможно иметь дубликаты.Если вам нужно перечислить всех подписчиков в любое время, используйте all_followers.keys
для получения идентификаторов.
Хэши занимают больше памяти, чем их эквиваленты массива, но это цена, которую вы должны заплатить за производительность.Я также подозреваю, что одним из крупных потребителей памяти здесь является множество отдельных списков подписчиков, которые создаются и, по-видимому, никогда не используются, поэтому, возможно, вы могли бы полностью пропустить этот шаг.
Ключевым моментом здесь является то, что массивОператор |
не очень эффективен, особенно при работе с очень большими массивами.