Un collega aveva bisogno di ordinare una matrice di oggetti ActiveRecord in un'app Rails. Ha provato l'ovvio Array.sort!
ma sembrava sorprendentemente lento, prendendo 32 secondi per un array di 3700 oggetti. Quindi, nel caso in cui questi grandi oggetti grassi rallentassero le cose, ha reimplementato l'ordinamento ordinando una serie di piccoli oggetti, quindi riordinando la matrice originale di oggetti ActiveRecord in modo che corrispondessero - come mostrato nel codice qui sotto. Tada! L'ordinamento ora richiede 700ms.Ruby: Perché Array.sort è lento per oggetti di grandi dimensioni?
Questo mi ha davvero sorpreso. Il metodo di ordinamento di Ruby finisce per copiare oggetti sul luogo anziché solo riferimenti? Sta usando Ruby 1.8.6/7.
def self.sort_events(events)
event_sorters = Array.new(events.length) {|i| EventSorter.new(i, events[i])}
event_sorters.sort!
event_sorters.collect {|es| events[es.index]}
end
private
# Class used by sort_events
class EventSorter
attr_reader :sqn
attr_reader :time
attr_reader :index
def initialize(index, event)
@index = index
@sqn = event.sqn
@time = event.time
end
def <=>(b)
@time != b.time ? @time <=> b.time : @sqn <=> b.sqn
end
end
vostro '<=> metodo' può anche essere scritta come: (@time <=> b.time) .nonzero '? o @sqn <=> b.sqn' –
Il registro di registrazione attivo mostra qualcosa di interessante durante l'ordinamento? Assicurati che sia configurato per registrare le query del database. –
Glenn - Grazie per il suggerimento su <=>. Wayne - Penso che potresti avere la risposta. Dopo non aver ottenuto alcuna risposta definitiva qui su SO ho preso in giro un piccolo script di test per ordinare alcuni oggetti ActiveRecord di grandi dimensioni (riempiti con alcune stringhe casuali) e quindi ho ripetuto l'ordinamento utilizzando la tecnica sopra riportata. Nessun miglioramento. Quindi lunedì suggerirò al mio collega di cercare gli effetti collaterali durante l'ordinamento. –