2010-01-10 36 views
21

Đây là sự tiếp nối của các câu hỏi như this one.SortedList so với SortedDictionary vs. Sort()

Có bất kỳ nguyên tắc nào để tinh chỉnh hiệu suất không? Tôi không có nghĩa là lợi nhuận trong big-O, chỉ cần tiết kiệm một số thời gian tuyến tính.

Ví dụ: số tiền phân loại trước được lưu trên SortedList hoặc SortedDictionary?

Giả sử tôi có một lớp người với 3 thuộc tính để sắp xếp, một trong số đó là tuổi trong năm. Tôi có nên xô các đối tượng trên tuổi đầu tiên?

Trước tiên tôi có nên sắp xếp trên một thuộc tính không, sau đó sử dụng danh sách/từ điển kết quả để sắp xếp trên hai thuộc tính, v.v ...?

Bất kỳ tối ưu hóa nào khác có thể lưu ý đến bạn?

+1

Bạn đã thử lược tả mã của mình để đảm bảo rằng việc khởi tạo các datasctructures được sắp xếp của bạn thực ra là nút cổ chai trong mã của bạn? –

+1

Cho đến nay nó là một câu hỏi giả định, nhưng có, đây sẽ là nút cổ chai, cho đến nay. – Martin

+0

Tôi không thể nhớ nhưng tôi cho rằng tôi giả định rằng tất cả các phương pháp đều có hiệu suất tiệm cận tương đương nhau và có thể khác nhau về hiệu suất trung bình (O (1)) tùy thuộc vào trường hợp sử dụng. – Martin

Trả lời

55

Vâng, đó là một chiến thắng dễ dàng trên SortedList. Chèn một mục yêu cầu tìm kiếm nhị phân (O (log (n)) để tìm điểm chèn, sau đó là List.Insert (O (n)) để chèn mục. Chèn() chiếm ưu thế, điền danh sách yêu cầu O (n^2) Nếu các mục nhập đã được sắp xếp thì Chèn sẽ sụp đổ thành O (1) nhưng không ảnh hưởng đến tìm kiếm. Populating bây giờ là O (nlog (n)) Bạn không lo lắng mức độ lớn của Oh, Việc phân loại đầu tiên luôn hiệu quả hơn Giả sử bạn có thể đủ khả năng yêu cầu lưu trữ tăng gấp đôi

SortedDictionary là khác nhau, nó sử dụng một cây đỏ đen Tìm điểm chèn yêu cầu O (log (n)). yêu cầu sau đó, điều đó cũng lấy O (log (n)), điền vào từ điển như vậy sẽ có O (nlog (n)) Sử dụng đầu vào sắp xếp không thay đổi nỗ lực để tìm điểm chèn hoặc cân bằng lại, nó vẫn là O (nlog (n)) Bây giờ các vấn đề Oh mặc dù, chèn đầu vào được sắp xếp đòi hỏi cây để consta nt tái cân bằng chính nó. Nó hoạt động tốt hơn nếu đầu vào là ngẫu nhiên, bạn không muốn đầu vào được sắp xếp.

Vì vậy, hãy điền SortedList với đầu vào được sắp xếp và điền vào SortedDictionary với đầu vào chưa được phân loại là cả O (nlog (n)). Bỏ qua chi phí cung cấp đầu vào được sắp xếp, Oh of SortedList nhỏ hơn Oh of SortedDictionary. Đó là một chi tiết thực hiện do cách List phân bổ bộ nhớ. Nó chỉ phải làm như vậy O (log (n)) lần, một cây đỏ đen phải phân bổ O (n) lần. Rất nhỏ Oh btw.

Đáng chú ý là không ai so sánh thuận lợi với việc đơn giản điền một Danh sách, sau đó gọi Sắp xếp(). Đó cũng là O (nlog (n)). Trong thực tế, nếu đầu vào đã được vô tình sắp xếp, bạn có thể bỏ qua cuộc gọi Sort(), điều này sụp đổ thành O (n). Phân tích chi phí bây giờ cần phải chuyển sang nỗ lực cần thiết để có được đầu vào được sắp xếp. Thật khó để bỏ qua sự phức tạp cơ bản của Sort(), O (nlog (n)). Nó có thể không được dễ dàng nhìn thấy, bạn có thể nhận được đầu vào được sắp xếp theo, nói, một truy vấn SQL. Nó sẽ chỉ mất nhiều thời gian hơn để hoàn thành.

Điểm sử dụng SortedList hoặc SortedDictonary là giữ bộ sưu tập được sắp xếp sau khi chèn. Nếu bạn chỉ lo lắng về populating nhưng không đột biến thì bạn không nên sử dụng những bộ sưu tập.

+2

Sidenote: Nếu dữ liệu có thể được sắp xếp bằng cách sử dụng phương pháp không so sánh chẳng hạn như Radix Sort thì việc phân loại có thể là giả tuyến tính (tùy thuộc vào độ dài của "cơ số" so với đầu vào) bị thu hẹp thành O (n) sắp xếp ngay cả đối với các đầu vào chưa được phân loại, trong trường hợp này tạo danh sách và sử dụng Sort() có thể nhanh hơn. – apokryfos

+0

Câu trả lời hữu ích, cảm ơn bạn! – namford

Các vấn đề liên quan