2010-09-08 17 views
10

Nói cách khác, điều nào sau đây sẽ nhanh hơn, nếu có?Trong C#, khi sử dụng Danh sách <T>, có tốt để lưu vào bộ đếm thuộc tính hoặc thuộc tính đủ nhanh không?

List<MyClass> myList; 
... 
... 
foreach (Whatever whatever in SomeOtherLongList) 
{ 
    ... 
    if (i < myList.Count) 
    { 
    ... 
    } 
} 

hoặc

List<MyClass> myList; 
... 
... 
int listCount = myList.Count; 
foreach (Whatever whatever in SomeOtherLongList) 
{ 
    ... 
    if (i < listCount) 
    { 
    ... 
    } 
} 

Cảm ơn :)

+2

Bạn đang yêu cầu chúng tôi làm gì? Bạn đã viết mã cả hai cách; nếu bạn muốn biết cách nào nhanh hơn trên máy của bạn thì hãy chạy cả hai, đo thời gian được thực hiện cho từng máy và sau đó bạn sẽ biết *. Bất cứ ai ở đây chỉ là * đoán *, hoặc đang cho bạn câu trả lời dựa trên những gì xảy ra trên * máy * của họ, không ai trong số đó cung cấp cho bạn câu trả lời mà bạn có thể dựa vào. Không có thay thế cho đo lường thực tế khi nói đến câu hỏi hiệu suất. –

Trả lời

16

Các Count chỉ là một số nguyên. nó không được tính khi bạn hỏi giá trị của nó. nó được 'tính toán trước' nên nó giống nhau. tùy chọn 1 dễ đọc hơn :)

+0

Không bao giờ biết điều đó. Vì vậy, trong trường hợp này, số đếm sẽ không được thực thi mỗi khi nó được gọi trong vòng lặp foreach? – Rob

+0

Nó có thể có những đặc điểm hoàn hảo giống nhau nhưng nó không nhất thiết phải là cùng một ngữ nghĩa. Nếu 'myList' được cập nhật thì giá trị được lưu trong bộ nhớ cache sẽ cũ. – LukeH

+0

Luke, bạn nói đúng, nhưng đó không hẳn là câu hỏi, đó là điều tốt nhất về tốc độ. Nếu bạn sẽ thay đổi 'List' của bạn trong vòng lặp, hơn là một câu hỏi hoàn toàn khác :) Rob, Các nhà phát triển của C# sẽ khá câm nếu họ tính toán lại nó mỗi lần bạn truy vấn giá trị mà bạn nghĩ? :) Khi có thay đổi trong danh sách, giá trị Đếm được cập nhật.chỉ như thế :) – Stefanvds

0

Đầu tiên là tùy chọn dễ đọc hơn và tốt hơn, bạn cũng có not wasting the memory of int (listCount).

sẽ không có bất kỳ khác biệt hiệu suất nào trong cả hai.

Đếm trong Danh mục được tự động định nghĩa một, một khi bạn tạo một danh sách

13

Đối List<T> có thực sự không cần đến bộ nhớ cache nó, vì nó chỉ là một tài sản đơn giản.

Tuy nhiên, phương pháp mở rộng Count() có thể được sử dụng trên bất kỳ IEnumerable có thể rất tốn kém, vì nó có thể cần liệt kê toàn bộ chuỗi để đếm nó (đối với danh sách nó chỉ sử dụng thuộc tính, liệt kê). Ngoài ra, nếu bạn chỉ cần biết nếu đếm không phải là số không, phương pháp mở rộng Any() được ưu tiên.

+1

thông tin hữu ích về' Bất kỳ() 'thuộc tính' so với 'Phương thức' khá rõ ràng :) – Stefanvds

3

Bạn có thể có một cái nhìn qua Reflector để nhìn vào việc thực hiện của Count:

public int Count 
{ 
    get 
    { 
     return this._size; 
    } 
} 

Như chúng ta có thể thấy, Count chỉ là một tài sản trả lại viên _size, mà luôn luôn updateted khi thêm/xóa mục đến/từ danh sách:

public void Add(T item) 
{ 
    if (this._size == this._items.Length) 
    { 
     this.EnsureCapacity(this._size + 1); 
    } 
    this._items[this._size++] = item; 
    this._version++; 
} 

public void RemoveAt(int index) 
{ 
    if (index >= this._size) 
    { 
     ThrowHelper.ThrowArgumentOutOfRangeException(); 
    } 
    this._size--; 
    if (index < this._size) 
    { 
     Array.Copy(this._items, index + 1, this._items, index, this._size - index); 
    } 
    this._items[this._size] = default(T); 
    this._version++; 
} 

vì vậy rõ ràng không cần phải lưu lại thuộc tính.

0

Caching rõ ràng sẽ nhanh hơn b/c bạn lưu các cuộc gọi hàm để nhận số ngay cả khi đó chỉ là một biến.

Vì giá trị có thể thay đổi giữa các lần lặp vòng nên trình biên dịch sẽ không loại bỏ các cuộc gọi hàm này vì nó có thể thay đổi ngữ nghĩa của mã.

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