Un colega necesitaba ordenar una matriz de objetos ActiveRecord en una aplicación de Rails. Intentó el obvio Array.sort!
pero parecía sorprendentemente lento, tomando 32s para una matriz de 3700 objetos. Así que solo en caso de que estos objetos grandes y gordos redujeran la velocidad de las cosas, reimplementó el género ordenando una serie de pequeños objetos, y luego reorganizando la matriz original de objetos ActiveRecord para que coincida, como se muestra en el siguiente código. Tada! El género ahora lleva 700ms.Ruby: ¿Por qué Array.sort es lento para objetos grandes?
Eso realmente me sorprendió. ¿El método de clasificación de Ruby termina copiando objetos sobre el lugar en lugar de solo referencias? Él está 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
Su '' <=> método también se puede escribir como: '.nonzero (@time <=> b.time)? o @sqn <=> b.sqn' –
¿El registro de registro activo muestra algo interesante que sucede durante el proceso? Asegúrese de que esté configurado para registrar las consultas de la base de datos. –
Glenn - Gracias por el consejo en <=>. Wayne - Creo que es posible que tenga la respuesta. Después de no obtener ninguna respuesta definitiva aquí en SO me burlé de un pequeño script de prueba para ordenar algunos objetos grandes de ActiveRecord (rellenos con algunas cadenas aleatorias) y luego repite el orden usando la técnica anterior. Ninguna mejora en absoluto. Así que el lunes le sugeriré a mi colega que tiene que buscar efectos secundarios durante el proceso. –