Tôi có một số IEnumerable<T>
và tôi cần một bản sao của nó. Bất cứ điều gì thực hiện IEnumerable<T>
sẽ làm tốt. Cách rẻ nhất để sao chép nó là gì? .ToArray()
có thể?Cách rẻ nhất để sao chép một IEnumerable <T>?
Trả lời
ToArray
không nhất thiết phải nhanh hơn ToList
. Chỉ cần sử dụng ToList
.
Điểm là miễn là bạn không biết số lượng phần tử của chuỗi gốc trước khi liệt kê, bạn kết thúc với việc thay đổi kích thước mảng và thêm các phần tử vào nó như List<T>
, vì vậy ToArray
sẽ phải thực hiện cùng một điều List<T>
nào. Bên cạnh đó, ToList
cung cấp cho bạn List<T>
và đẹp hơn một mảng thô.
Tất nhiên, nếu bạn biết loại bê tông của thể hiện IEnumerable<T>
, có thể có các phương pháp nhanh hơn, nhưng đó không phải là nguyên nhân cho vấn đề.
Lưu ý phụ: sử dụng mảng (trừ khi bạn phải) được cho là tối ưu hóa vi mô và phải là avoidedmost of the time.
Cách thứ hai đến rẻ nhất là nói new List<T>(myEnumerable).ToArray()
. Cách rẻ nhất là sử dụng .ToArray()
(từ LINQ) hoặc, nếu bạn không có C# 3.5, để tạo bộ đệm của riêng bạn và thêm vào nó trong khi tăng gấp đôi kích thước của nó, sau đó cắt nó ở cuối.
Enumerable::ToArray
và Enumerable::ToList
cuối cùng sử dụng kỹ thuật tương tự để nhận các phần tử từ nguồn vào bộ đệm mảng bên trong, chúng sẽ phân bổ bộ đệm mới tăng gấp đôi kích thước, ghi nhớ và tiếp tục thêm các phần tử, lặp lại quá trình này cho đến khi liệt kê nguồn hoàn tất. Sự khác biệt cuối cùng là ToArray
, sử dụng triển khai thực hiện Buffer<T>
trong nội bộ, sau đó phải phân bổ chính xác kích thước Array
và sao chép các phần tử vào đó trước khi trả lại kết quả. Mặt khác, ToList
chỉ cần trả lại List<T>
với bộ đệm mảng có khả năng được tạo một phần (có khả năng) bên trong nó.
Cả hai hiện thực cũng có một tối ưu hóa mà nếu nguồn IEnumerable
là một ICollection
họ sẽ thực sự phân bổ chính xác kích thước bộ đệm ngay để bắt đầu với việc sử dụng ICollection::Count
và sau đó sử dụng ICollection::CopyTo
từ nguồn để điền vào bộ đệm của họ. Cuối cùng, bạn sẽ thấy rằng chúng hoạt động gần như giống hệt nhau trong hầu hết các trường hợp, nhưng List<T>
về mặt kỹ thuật là lớp "nặng hơn" để treo vào cuối và ToArray
có thêm phân bổ + memcpy ở cuối (nếu nguồn không phải là ICollection
) để có thể quay lại đúng mảng có kích thước chính xác. Tôi thường gắn bó với ToList
bản thân mình trừ khi tôi biết tôi cần phải chuyển kết quả đến thứ gì đó yêu cầu một mảng như nói có thể Task::WaitAll
.
Tôi sắp đề xuất khả năng sử dụng .AsParallel().ToList()
nếu bạn có TPL theo ý của mình, nhưng thử nghiệm không chính thức trên máy tính xách tay lõi kép của tôi cho thấy nó chậm hơn 7 lần so với chỉ .ToList()
. Vì vậy, hãy liên kết với Mehrdad'sanswer.
+1 Đó có khả năng là một lựa chọn tốt, và tùy thuộc vào bản chất của đối tượng người nhận, nó có thể nhanh hơn rất nhiều, nhưng điều đó rơi vào danh mục "không phải là germane đến điểm". –
Tôi biết điều này khá cũ ...
Tại sao bạn không thể làm điều gì đó như thế này ...
IEnumerable <T> original = {... chèn mã vào đây để điền ...};
IEnumerable <T> copy = (từ hàng trong hàng chọn ban đầu);
Tôi đã sử dụng phương pháp này trước khi trì hoãn việc tải bản sao và các phần tử của nó cho đến khi tôi thực sự cần chúng, cộng với, tôi không thay đổi kiểu dữ liệu cơ bản của "gốc" thành kiểu danh sách.
Chọn danh tính không thực sự mang lại cho bạn bất kỳ điều gì ở đây. Điều này không thực sự có chức năng khác với việc chỉ sao chép tham chiếu đến 'IEnumerable' khác, ngoài việc này thêm một chút chi phí phụ trội vào thời gian chạy và ngăn cản việc truyền đến kiểu cơ bản. Nếu bạn muốn có một ảnh chụp nhanh về những gì mà trình tự trông giống tại một thời điểm 'ToList' là phương pháp đúng đắn. Nếu bạn không, và bạn muốn một chuỗi được tạo ra trong cùng một trang viên giống như trình tự khác, chỉ cần sao chép tham chiếu chính nó; không cần phải làm gì nữa. – Servy
- 1. Cách tốt nhất để sao chép/sao chép sâu một từ điển .NET chung là gì <string, T>?
- 2. Làm thế nào để chuyển đổi một IEnumerable <IEnumerable <T>> thành IEnumerable <T>
- 3. IEnumerable <IEnumerable <T>> để IEnumerable <T> sử dụng LINQ
- 4. Tại sao IEnumerable <T> kế thừa từ IEnumerable?
- 5. Whats cách tốt nhất để sao chép/sao chép dự án thành một mới với git?
- 6. Cách dễ nhất để sao chép/sao chép một cá thể tài liệu mongoose?
- 7. Cách nhanh nhất để sao chép một GregorianCalendar?
- 8. Cách nhanh nhất để sao chép một bảng trong mysql?
- 9. Tại sao IEnumerable <struct> không thể xem như IEnumerable <object>?
- 10. Flatten IEnumerable <IEnumerable <>>; hiểu Generics
- 11. Tại sao một chức năng mất IEnumerable <interface> không chấp nhận IEnumerable <class>?
- 12. Cách tốt nhất để chuyển đổi IEnumerable <char> thành chuỗi?
- 13. Cách sao chép hoặc sao chép một mảng các mảng
- 14. Hợp nhất hai IEnumerable <T> s
- 15. Cách đơn giản nhất để sao chép int thành byte []
- 16. Cách tốt nhất để sao chép danh sách là gì?
- 17. Cách nhanh nhất để sao chép các tệp trong Java
- 18. IEnumerable <string> chuỗi
- 19. Cách xoay vòng IEnumerable <T>
- 20. Cách yêu thích để tạo một chuỗi số <T> IEnumerable mới từ một giá trị duy nhất?
- 21. Tại sao TreeNodeCollection không ngụ ý IEnumerable <TreeNode>?
- 22. Làm thế nào để chuyển đổi một IEnumerable <Task<T>> để IObservable <T>
- 23. Cách sao chép chính xác Danh sách <MyObject>?
- 24. Sự khác nhau giữa IEnumerable và IEnumerable <T>?
- 25. Làm cách nào để sao chép/sao chép một số loại UIView cho iOS?
- 26. Làm thế nào để nối hai IEnumerable <T> vào một IEnumerable mới <T>?
- 27. Cách dễ nhất để sao chép một dataview đến một datatable trong C#?
- 28. Cách rẻ nhất để triển khai một ứng dụng ASP.Net MVC là gì?
- 29. Cách rẻ/nhanh để băm bitmap?
- 30. Tại sao không Cast <double>() hoạt động trên IEnumerable <int>?
Để lưu ý chúng hầu như tương đương. – Vadim
@Yads: chính xác. –
+1. Trong thực tế, Mono ['Enumerable.ToArray'] (https://github.com/mono/mono/blob/master/mcs/class/System.Core/System.Linq/Enumerable.cs#L2794) sử dụng' Danh sách mới (nguồn) .ToArray() ', trừ khi' IEnumerable 'xảy ra là' ICollection '. Tôi sẽ không ngạc nhiên nếu MS là tương tự. –