Mam następujący scenariusz:wielka manipulacja tablica jest bardzo powolny w Ruby
I potrzeba, aby dowiedzieć się unikalną listę identyfikatorów całej bardzo dużego zestawu.
Na przykład mam 6000 tablic identyfikatorów (lista obserwatorów), każda może mieć rozmiar od 1 do 25000 (lista ich obserwatorów).
Chcę uzyskać unikalną listę identyfikatorów we wszystkich tych tablicach identyfikatorów (unikalnych obserwatorów). Kiedy już to zrobię, muszę odjąć kolejną listę (kolejną listę osób obserwujących) identyfikatorów i uzyskać końcową liczbę.
Ostateczny zestaw unikalnych identyfikatorów rośnie do około 60 000 000 rekordów. W rubinach dodając tablice do dużej tablicy, zaczyna się bardzo powoli około kilku milionów. Dodanie do zestawu trwa początkowo 1 sekundę, a następnie rośnie do 4 sekund na poziomie 2 milionów (brak miejsca w pobliżu miejsca, w którym muszę się udać).
Napisałem program testowy w języku Java i robi to wszystko w mniej niż minutę.
Może robię to nieefektywnie w rubinie lub jest inny sposób. Ponieważ mój główny kod jest zastrzeżona ja napisałem prosty program testowy do symulacji problem:
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
Wszelkie sugestie, nadszedł czas, aby przełączyć się jruby i przenieść rzeczy jak to Java?
Chciałem tylko zwróć uwagę, że masz 'loop_counter = 0' w swojej sekcji czasowej. Chociaż podejście dostępu do tablicy jest ** znacznie wolniejsze ** niż sugerowane podejście hash, czas pętli nie rośnie tak szybko. Przy 2 milionach rekordów czas pętli wynosi trzy i pół sekundy na mojej maszynie, od początkowego czasu pętli 0,09 sekundy. –
Ruby jest szybkie, robisz to w niewłaściwy sposób. Jest to naprawdę przypadek użycia bazy danych, a nie manipulacja w pamięci w jakimkolwiek języku. Dobry DBM może szybko znaleźć różne wartości i powiązania, wszystkie zanim zapytanie wyjdzie z bazy danych. Polecę [Sequel] (http://sequel.rubyforge.org/) jako świetną bazę danych ORM, która ułatwi utrzymanie i zapytanie. –