2011-12-11 22 views

Trả lời

10

Thực tế cùng một lượng bộ nhớ (về mặt kỹ thuật, List có thể sẽ tiêu thụ một số chi tiết vì nó đã phân bổ quá mức để có thể phát triển dễ dàng hơn).

Bộ sưu tập chung trong .NET không cần phải đóng hộp các mục mà chúng giữ, đó sẽ là bộ nhớ lớn và hiệu năng.

+3

Bạn muốn nói rằng Danh sách <> là một mảng khi nói đến triển khai? –

+2

@Daniel: Vâng, một mảng có thể phát triển. – sepp2k

+1

@ DanielMošmondor: [Có] (http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx): * Lớp List (Of T) là tương đương chung của lớp ArrayList. Nó thực hiện giao diện chung IList (Of T) sử dụng một mảng có kích thước được tăng động theo yêu cầu. * – Jon

1

Tôi yêu cầu rằng vì theo kiến ​​thức của tôi, .NET không có chuyên môn về mẫu (generics).

.Net không có chuyên môn về mẫu theo nghĩa bạn (với tư cách là người lập trình) có thể cung cấp mã khác nhau tùy thuộc vào loại đối số. Nhưng trình biên dịch vẫn có thể (và không) tạo mã khác nhau cho các kiểu giá trị hơn là kiểu tham chiếu, nghĩa là các kiểu giá trị (không giống trong Java) không được đóng hộp khi đưa vào một thùng chứa chung. Chúng được lưu trữ hiệu quả.

5

List<T> sở hữu một mảng T[]. Nó sử dụng chiến lược tăng trưởng theo hàm mũ cho mảng này, do đó danh sách có các thành phần n thường có mảng sao lưu có kích thước lớn hơn n. Ngoài ra các mảng nhỏ hơn cần phải được thu gom rác thải, có thể gây phiền nhiễu nếu đủ lớn để có trên LoH.

Nhưng bạn có thể tránh điều này bằng cách chỉ định dung lượng theo cách thủ công, ví dụ như tham số hàm tạo. Sau đó, một mảng duy nhất với dung lượng mong muốn sẽ được cấp phát, vì vậy bạn tránh cả hai vấn đề trên.

Ngoài ra List<T> có một chi phí nhỏ O (1) cho chính đối tượng danh sách.


Nhưng không có chi phí cho mỗi phần tử khi sử dụng Generics. Thời gian chạy tạo ra một phiên bản chuyên biệt cho mỗi loại giá trị bạn vượt qua. Không có quyền anh hùng nào xảy ra.

Nhưng bạn không thể sử dụng chuyên môn mẫu kiểu C++, nơi bạn thực hiện quá tải việc thực hiện một cách hiệu quả đối với các thông số loại nhất định. Tất cả các instantiations chung đều có cùng mã C#.

tức là không có mã IL chuyên biệt, nhưng mỗi loại giá trị sẽ được triển khai mã máy chuyên biệt dựa trên cùng một mã nguồn.

1

Sử dụng danh sách thực tế hơn là sử dụng mảng đồng bằng. Chìa khóa để thực hiện và tiêu thụ bộ nhớ là Dung lượng của một danh sách. Theo mặc định, nó bắt đầu với giá trị là 4 và tăng lên 8, 16, 32, 64, ... bất cứ khi nào các phần tử của danh sách đạt đến dung lượng đã xác định. Mỗi gia số được dịch sang phân bổ lại nội bộ và Array.Copy. Vì vậy, nếu bạn có một danh sách với 1000 mục và bạn mong đợi 100 mục trong một ngày, bạn có thể khởi tạo danh sách với dung lượng 1200 (tỷ lệ lỗi trong dự đoán 100%). Bằng cách này bạn sẽ tránh việc phân bổ lại cho 2000 mục bất cứ khi nào bạn thêm mục 10001, và tất nhiên việc phân bổ lại liên tục và Array.Copy để điền nó với 1000 mục hiện có.

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