Một đồng nghiệp cần sắp xếp một mảng các đối tượng ActiveRecord trong ứng dụng Rails. Ông đã cố gắng rõ ràng Array.sort!
nhưng nó dường như đáng ngạc nhiên chậm, lấy 32s cho một mảng của 3700 đối tượng. Vì vậy, trong trường hợp nó là những vật thể béo lớn làm chậm mọi thứ, anh ta reimplemented sắp xếp bằng cách sắp xếp một mảng các đối tượng nhỏ, sau đó sắp xếp lại mảng ban đầu của các đối tượng ActiveRecord để khớp - như được hiển thị trong mã bên dưới. Tada! Các loại bây giờ mất 700ms.Ruby: Tại sao Array.sort lại làm chậm đối tượng lớn?
Điều đó thực sự làm tôi ngạc nhiên. Phương pháp sắp xếp của Ruby có kết thúc sao chép các đối tượng về địa điểm thay vì chỉ tham chiếu không? Anh ấy đang sử dụng 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
của bạn '' <=> phương pháp cũng có thể được viết như sau: '(@time <=> b.time) .nonzero? hoặc @sqn <=> b.sqn' –
Nhật ký ghi lại hoạt động có hiển thị bất kỳ điều gì thú vị xảy ra trong quá trình sắp xếp không? Hãy chắc chắn rằng nó được cấu hình để đăng nhập truy vấn cơ sở dữ liệu. –
Glenn - Cảm ơn bạn đã có mẹo trên <=>. Wayne - Tôi nghĩ bạn có thể có câu trả lời. Sau khi không nhận được bất kỳ câu trả lời dứt khoát nào ở đây, tôi đã giả lập một kịch bản thử nghiệm nhỏ để sắp xếp một số đối tượng ActiveRecord lớn (được đệm bằng một số chuỗi ngẫu nhiên) và sau đó lặp lại sắp xếp bằng cách sử dụng kỹ thuật ở trên. Không có cải thiện chút nào. Vì vậy, vào thứ hai tôi sẽ đề nghị với đồng nghiệp của tôi rằng anh ta có một cái nhìn cho các tác dụng phụ trong quá trình sắp xếp. –