Lưu ý: câu trả lời này áp dụng nhiều hơn cho Java so với C#, vì C# không có chỉ mục trên LinkedLists
, nhưng tôi nghĩ điểm chung vẫn giữ.
Nếu list
bạn đang làm việc với sẽ xảy ra là một LinkedList
, hiệu suất của indexer-code (mảng kiểu việc truy cập) là tồi tệ hơn rất nhiều so với sử dụng IEnumerator
từ foreach
, cho các danh sách lớn.
Khi bạn truy cập phần tử 10.000 trong một LinkedList
sử dụng cú pháp chỉ mục: list[10000]
, danh sách được liên kết sẽ bắt đầu tại nút đầu và đi qua Next
-pointer mười nghìn lần, cho đến khi nó đến đúng đối tượng. Rõ ràng, nếu bạn làm điều này trong một vòng lặp, bạn sẽ nhận được:
list[0]; // head
list[1]; // head.Next
list[2]; // head.Next.Next
// etc.
Khi bạn gọi GetEnumerator
(ngầm sử dụng forach
-syntax), bạn sẽ nhận được một đối tượng IEnumerator
rằng có một con trỏ đến nút đầu. Mỗi lần bạn gọi MoveNext
, con trỏ được chuyển đến nút kế tiếp, như vậy:
IEnumerator em = list.GetEnumerator(); // Current points at head
em.MoveNext(); // Update Current to .Next
em.MoveNext(); // Update Current to .Next
em.MoveNext(); // Update Current to .Next
// etc.
Như bạn có thể thấy, trong trường hợp của LinkedList
s, phương pháp mảng indexer trở nên chậm hơn và chậm hơn, các bạn còn loop (nó phải đi qua cùng một đầu con trỏ hơn và hơn nữa). Trong khi IEnumerable
chỉ hoạt động trong thời gian không đổi.
Tất nhiên, như Jon nói điều này thực sự phụ thuộc vào loại list
, nếu list
không phải là LinkedList
, nhưng một mảng, hành vi hoàn toàn khác.
Nguồn
2009-07-14 12:03:23
tôi tưởng tượng rằng nó không thực sự quan trọng. Nếu bạn đang gặp vấn đề về hiệu suất, nó gần như chắc chắn không phải do điều này. Không phải là bạn không nên đặt câu hỏi ... – darasd
Nó lo lắng cho tôi rằng một số câu trả lời ở đây dường như được đăng bởi những người chỉ đơn giản là không có khái niệm về một vòng lặp bất cứ nơi nào trong não của họ, và do đó không có khái niệm về điều tra viên hoặc con trỏ. –
Mã thứ hai đó sẽ không biên dịch. System.Object không có thành viên nào được gọi là 'value' (trừ khi bạn thực sự xấu xa, đã định nghĩa nó như là một phương thức mở rộng và đang so sánh các đại biểu). Mạnh mẽ loại của bạn foreach. – Trillian