2012-04-13 30 views
11

Tôi thường viết mã như sau:Đếm và Dung lượng nhanh như thế nào?

if (list.Count > 0) { } 

Điều này có hiệu quả không? Có cái nhìn hoạt động này như:

  • Duyệt qua danh sách và đếm phần tử của nó
  • Kết quả: 986.000 yếu tố
  • là 986.000 lớn hơn 0?
  • trở lại đúng

Hoặc như thế này:

  • Lấy số lưu trữ các phần tử trong danh sách (986.000)
  • là 986.000 lớn hơn 0?
  • trở lại đúng

Đó là, để có được số phần tử trong danh sách, bạn có để đếm tất cả các cách thức thông qua danh sách, hoặc là số phần tử ghi nơi nào đó? Và đây có phải là trường hợp cho tất cả các lớp học ICollection không?

Điều gì về số Capacity của danh sách?

Trả lời

33

Tôi thường viết mã như sau: if (list.Count > 0) { } Điều này có hiệu quả không?

Có. Điều đó lấy số đếm trong danh sách, được lưu trữ trong một trường bên trong danh sách và so sánh nó với số không.

Bây giờ một câu hỏi mà bạn không đặt câu hỏi:

gì về if (sequence.Count() > 0) { }? (Chú ý dấu ngoặc trên Count().)

Chúng tôi thẩm vấn trình tự thời gian chạy để xem nếu nó là một danh sách đó có một tài sản có thể được tính toán một cách hiệu quả Count. Nếu có, chúng tôi gọi nó. Nếu không, chúng tôi tính toàn bộ chuỗi một mục tại một thời điểm, và sau đó so sánh nó với số không.

Điều đó cực kỳ không hiệu quả?

Có.

Điều gì sẽ hiệu quả hơn?

if (sequence.Any())

Tại sao là hiệu quả hơn?

Vì nó cố gắng lặp qua thành phần một. Nếu thành công, thì Any là đúng; nếu không thành công thì Any là sai. Bạn không cần đếm số lượng thạch trong bình để biết liệu có nhiều hơn 0 không. Bạn chỉ cần xem xét xem có ít nhất một người không.

Ngoài việc được hiệu quả hơn đáng kể, mã giờ đây giống như ý nghĩa của mã. Nếu bạn có ý định hỏi "có bất kỳ mục nào trong danh sách không?" sau đó hỏi "có bất kỳ mục nào trong danh sách không?" và không phải "số lượng các mục trong danh sách lớn hơn không?"

Thuộc tính Capacity của danh sách là gì?

Điều đó cho bạn biết số lượng không gian đã được phân bổ trước trong cấu trúc dữ liệu nội bộ của danh sách. Đó là số lượng các mục mà danh sách có thể lưu trữ trước khi nó phải cấp phát bộ nhớ nhiều hơn.

+0

"Chúng tôi thẩm vấn trình tự trong thời gian chạy để xem nếu nó là một danh sách có một tính Count có thể được tính hiệu quả." Ý bạn là như thế nào? Bạn có kiểm tra một thuộc tính được gọi là 'Đếm' hay bạn kiểm tra xem 'ICollection ' có được triển khai không? Trường hợp thứ hai có các trường hợp đặc biệt buồn cười nếu bạn sử dụng hiệp phương sai của 'IEnumerable '. – CodesInChaos

+0

@CodeInChaos: Nhìn qua Phản chiếu cho thuộc tính có tên Đếm sẽ chậm và không đáng tin cậy. Chúng tôi tìm kiếm một giao diện thực hiện. Và có, bạn có thể nhận được âm tính giả là kết quả của các vấn đề hiệp phương sai. Nếu nó đau khi bạn làm điều đó thì đừng làm thế. –

+2

@CodeInChaos nếu kiểm tra 'ICollection 'không thành công, thì mã sẽ kiểm tra' ICollection' không chung chung. Vì vậy, hầu hết các bộ sưu tập khung được an toàn từ vấn đề hiệp phương sai. – phoog

2

Sử dụng mã này thay thế: list.Any(). Nó có thể chậm hơn List<>.Count, nhưng sẽ hoạt động đối với bất kỳ IEnumerable <> theo cách hiệu quả nhất.

Capacity có thể lớn hơn Count. Nó được sử dụng khi bạn có kế hoạch để thêm rất nhiều mặt hàng sau này.

Imlementation của List.Count là như sau (nó thực sự là O (1)):

public int Count 
{ 
    get 
    { 
    return this._size; // this is a field 
    } 
} 
+2

Trong khi '.Any()' là thích hợp hơn với '.Count()> 0', nó hơi kém hiệu quả vì nó tạo ra một điều tra viên trên bộ sưu tập. – Gabe

+0

fot Danh sách hoặc bất kỳ bộ sưu tập nào lưu trữ c –

2

Count là O(1) hoạt động trên danh sách.

Đó là cách nhanh nhất có thể.

Đếm: Đây là một số yếu tố có trong danh sách thực tế.

capcity: Giải thích tài liệu tốt hơn:

Gets hoặc đặt tổng số của các yếu tố cấu trúc dữ liệu nội bộ thể giữ mà không thay đổi kích thước.

1

Dung lượng không cho bạn biết có bao nhiêu đối tượng trong danh sách của bạn - chỉ bao nhiêu danh sách đã sẵn sàng.

Từ MSDN:

Capacity is the number of elements that the List<T> can store before resizing is required, while Count is the number of elements that are actually in the List<T>. 

List.Count là siêu nhanh và là một đặc tính truy cập trong khi List.Count() là từ IEnumerable và tôi tin rằng đã làm một thống kê toàn diện thông qua danh sách.

6

Thuộc tính Count trong List<T> - và tất cả các hoạt động khác ICollection<T> trong BCL - là hoạt động O (1), có nghĩa là số lượng phần tử trong danh sách nhanh và độc lập.

Cũng tồn tại phương thức tiện ích Count() có thể được gọi trên bất kỳ IEnumerable<T> nào. Phương thức này là O (n), có nghĩa là thời gian chạy của nó phụ thuộc vào số phần tử trong số đếm được. Tuy nhiên, có một ngoại lệ: Nếu số đếm thực sự là việc triển khai ICollection<T> hoặc ICollection, nó sử dụng thuộc tính Count làm cho nó trở lại hoạt động O (1).


Thuộc tính Capacity thường không có gì bạn cần phải lo lắng.

+1

Vâng, xem xét rằng op nói về 986.000 yếu tố trong danh sách quản lý thông minh về Năng lực ở đúng nơi * có thể * mang lại những lợi ích đáng kể. – Tigran

+0

Dung lượng được tăng gấp đôi mỗi khi bị trúng, do đó việc quản lý dung lượng chỉ mang lại lợi ích thực sự nếu bạn đang điền vào nhiều danh sách. –

+0

Đó không phải ý tôi là: nó * có thể * mang lại lợi ích trong một số trường hợp (ví dụ chương trình CAD) – Tigran

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