Lý do rằng mã đặc biệt là chậm là bởi vì nó làm việc trên nguyên thủy nhưng nó sử dụng các hoạt động chung, vì vậy nguyên thủy phải được đóng hộp. (Điều này có thể được cải thiện nếu List
và tổ tiên của nó là chuyên ngành.) Điều này có thể sẽ làm chậm những thứ xuống bởi một yếu tố của 5 hoặc hơn.
Ngoài ra, về mặt thuật toán, các thao tác này hơi tốn kém, bởi vì bạn tạo toàn bộ danh sách và sau đó tạo danh sách hoàn toàn mới ném một vài thành phần của danh sách trung gian. Nếu bạn đã làm nó trong một swoop, sau đó bạn muốn được tốt hơn. Bạn có thể làm điều gì đó như:
list collect (case e if (e*2>10) => e*2)
nhưng nếu tính toán e*2
thực sự đắt tiền? Sau đó, bạn có thể
(List[Int]() /: list)((ls,e) => { val x = e*2; if (x>10) x :: ls else ls }
ngoại trừ việc điều này sẽ xuất hiện ngược. (Bạn có thể đảo ngược nó nếu cần thiết, nhưng điều đó đòi hỏi phải tạo ra một danh sách mới, mà lại không phải là một thuật toán lý tưởng.)
Tất nhiên, bạn có cùng một loại vấn đề về thuật toán trong Java nếu bạn đang sử dụng một cách đơn giản danh sách liên kết - danh sách mới của bạn sẽ kết thúc ngược, hoặc bạn phải tạo ra hai lần, trước tiên là ngược lại và sau đó chuyển tiếp hoặc bạn phải xây dựng nó với đệ quy (không đuôi) (dễ dàng trong Scala, nhưng không thể dùng được cho loại điều này trong cả hai ngôn ngữ kể từ khi bạn sẽ xả stack), hoặc bạn phải tạo một danh sách có thể thay đổi và sau đó giả vờ sau đó rằng nó không thể thay đổi được. (Trong đó, tình cờ, bạn cũng có thể làm ở Scala - xem mutable.LinkedList
.)
Nguồn
2011-02-04 15:02:35
Câu trả lời này có vấn đề, nhưng không cung cấp giải pháp tốt đẹp. – Raphael
@Raphael - Không thực sự có một trạng thái hiện tại của thư viện. 'view' /' force' sẽ không cứu bạn khi bạn làm việc với nguyên thủy. –
Nếu 'e * 2' đắt tiền, thì chi phí để có bước trung gian sẽ giảm đi. Có thể vấn đề về bộ nhớ, nếu bạn xử lý một lượng lớn dữ liệu. – ziggystar