Phương pháp Linq Count(
) có nhanh hơn hoặc chậm hơn List<>.Count
hoặc Array.Length
không?Là số đếm Linq() nhanh hơn hoặc chậm hơn List.Count hoặc Array.Length?
Trả lời
Nói chung Chậm hơn. Tổng số LINQ nói chung là hoạt động O(N)
trong khi List.Count
và Array.Length
đều được đảm bảo là O(1)
.
Tuy nhiên, một số trường hợp LINQ sẽ đặc biệt có thông số IEnumerable<T>
bằng cách truyền tới một số loại giao diện nhất định như IList<T>
hoặc ICollection<T>
. Sau đó, nó sẽ sử dụng phương thức Đếm đó để thực hiện thao tác Count()
thực tế. Vì vậy, nó sẽ quay trở lại xuống O(1)
. Nhưng bạn vẫn phải trả chi phí nhỏ cho cuộc gọi diễn viên và giao diện.
@Marc, tôi đã thêm cavaet đó. – JaredPar
Tôi không chắc chắn, nhưng tôi nghĩ rằng nếu List.Count() được chạy trên một IQueryable nó sẽ thực hiện lệnh select count (*) sql. nhưng nếu List.Count được chạy, nó sẽ liệt kê tất cả các mục và sau đó trả về số đếm. Nếu sau này, List.Count() sẽ nhanh hơn hầu hết thời gian. – Jose
@Jared, Marcs trả lời là chính xác hơn, kiểm tra chỉ được thực hiện cho ICollection
Tôi tin rằng nếu bạn gọi Linq.Count() trên ICollection hoặc IList (như ArrayList hoặc List) thì nó sẽ trả về giá trị của thuộc tính Count. Vì vậy, hiệu suất sẽ giống nhau về các bộ sưu tập đơn giản.
ArrayList không phải là IEnumerable
Phương pháp Enumerable.Count()
kiểm tra ICollection<T>
, bằng cách sử dụng .Count
- vì vậy trong trường hợp mảng và danh sách, nó không hiệu quả hơn nhiều (chỉ cần thêm một mức độ gián tiếp).
Trên thực tế với mảng bạn nhận được 2 lớp indirection, xem câu trả lời của tôi: p –
Tôi sẽ nói điều đó tùy thuộc vào Danh sách. Nếu nó là một IQueryable là một bảng trong một db một nơi nào đó thì Count() sẽ là nhanh hơn nhiều bởi vì nó không phải tải tất cả các đối tượng. Nhưng nếu danh sách là trong bộ nhớ tôi sẽ đoán rằng tài sản Count sẽ nhanh hơn nếu không giống nhau.
Marc có câu trả lời đúng nhưng ma quỷ là chi tiết.
Trên máy tính của tôi:
- Đối với mảng .Length là nhanh hơn so với Count()
- Đối Lists Count là nhanh hơn so với Count() khoảng 10 lần khoảng 100 lần - Lưu ý: Tôi sẽ mong đợi hiệu suất tương tự từ tất cả các Bộ sưu tập thực hiện
IList<T>
Mảng bắt đầu chậm hơn kể từ .Lĩnh vực chỉ liên quan đến một lớp vô hướng. Vì vậy .Count trên mảng bắt đầu chậm hơn 10x (trên máy tính của tôi), có thể là một trong những lý do đó giao diện được thực hiện một cách rõ ràng. Hãy tưởng tượng nếu bạn có một đối tượng với hai thuộc tính công khai, .Count và .Length. Cả hai đều làm điều tương tự nhưng .Count chậm hơn 10X.
Tất nhiên, điều này thực sự tạo ra nhiều sự khác biệt vì bạn sẽ phải đếm mảng của mình và liệt kê hàng triệu lần mỗi giây để cảm nhận hiệu suất.
Code:
static void TimeAction(string description, int times, Action func) {
var watch = new Stopwatch();
watch.Start();
for (int i = 0; i < times; i++) {
func();
}
watch.Stop();
Console.Write(description);
Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}
static void Main(string[] args) {
var array = Enumerable.Range(0, 10000000).ToArray();
var list = Enumerable.Range(0, 10000000).ToArray().ToList();
// jit
TimeAction("Ignore and jit", 1 ,() =>
{
var junk = array.Length;
var junk2 = list.Count;
array.Count();
list.Count();
});
TimeAction("Array Length", 1000000,() => {
var tmp1 = array.Length;
});
TimeAction("Array Count()", 1000000,() =>
{
var tmp2 = array.Count();
});
TimeAction("Array Length through cast", 1000000,() =>
{
var tmp3 = (array as ICollection<int>).Count;
});
TimeAction("List Count", 1000000,() =>
{
var tmp1 = list.Count;
});
TimeAction("List Count()", 1000000,() =>
{
var tmp2 = list.Count();
});
Console.ReadKey();
}
Kết quả:
Array Length Time Elapsed 3 ms Array Count() Time Elapsed 264 ms Array Length through cast Time Elapsed 16 ms List Count Time Elapsed 3 ms List Count() Time Elapsed 18 ms
Một số thêm thông tin - LINQ Đếm - sự khác biệt giữa việc sử dụng nó và không thể khổng lồ - và điều này không phải là qua ' bộ sưu tập lớn. Tôi có một bộ sưu tập được hình thành từ linq cho các đối tượng với khoảng 6500 mục (lớn .. nhưng không lớn bằng bất kỳ phương tiện nào). Count() trong trường hợp của tôi mất vài giây. Chuyển đổi thành một danh sách (hoặc mảng, whatver) số lượng là gần như ngay lập tức. Việc đếm số này trong vòng lặp bên trong có nghĩa là tác động có thể rất lớn. Đếm đếm qua tất cả mọi thứ.Một mảng và một danh sách đều là 'tự nhận thức' về độ dài của chúng và không cần liệt kê chúng. Bất kỳ câu lệnh debug nào (log4net cho ex) tham chiếu đến số đếm này() cũng sẽ làm chậm mọi thứ xuống đáng kể. Làm cho bạn một ưu và nếu bạn cần phải tham khảo này thường tiết kiệm kích thước đếm và chỉ gọi nó một lần trên một bộ sưu tập LINQ trừ khi bạn chuyển đổi nó thành một danh sách và sau đó có thể tham khảo mà không có một hit hiệu suất.
Đây là bài kiểm tra nhanh về những gì tôi đã nói ở trên. Lưu ý mỗi khi chúng ta gọi Count() kích thước bộ sưu tập của chúng ta thay đổi .. do đó việc đánh giá diễn ra, nhiều hơn một hoạt động 'đếm' dự kiến. Chỉ cần một cái gì đó để nhận thức được:)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LinqTest
{
class TestClass
{
public TestClass()
{
CreateDate = DateTime.Now;
}
public DateTime CreateDate;
}
class Program
{
static void Main(string[] args)
{
//Populate the test class
List list = new List(1000);
for (int i=0; i<1000; i++)
{
System.Threading.Thread.Sleep(20);
list.Add(new TestClass());
if(i%100==0)
{
Console.WriteLine(i.ToString() + " items added");
}
}
//now query for items
var newList = list.Where(o=> o.CreateDate.AddSeconds(5)> DateTime.Now);
while (newList.Count() > 0)
{
//Note - are actual count keeps decreasing.. showing our 'execute' is running every time we call count.
Console.WriteLine(newList.Count());
System.Threading.Thread.Sleep(500);
}
}
}
}
list.Where trả về một IEnumerable để bạn không có phím tắt với Count() ... nếu bạn thực hiện nó, bạn sẽ thấy perf khá tốt (ví dụ: 'list.Where (o => o.CreateDate.AddSeconds (5)> DateTime .Now) .ToList() ') –
- 1. Array.Count() chậm hơn nhiều so với List.Count()
- 2. Đó là nhanh hơn, equalsIgnoreCase hoặc compareToIgnoreCase
- 3. unordered_map: cái nào tìm nhanh hơn() hoặc đếm()?
- 4. IN hoặc OR nhanh hơn?
- 5. viết hoặc printf, nhanh hơn?
- 6. SQL & PHP - Đó là mysql_num_rows() hoặc 'select count()' nhanh hơn?
- 7. Điều gì là nhanh hơn: JMP hoặc chuỗi NOP?
- 8. Hoạt động nhanh hơn, re.match/search hoặc str.find là gì?
- 9. Nhanh hơn là gì? File_exist hoặc truy vấn MySQL?
- 10. Đó là nhanh hơn, 'find -exec' hoặc 'tìm | xargs -0 '?
- 11. Là chất nền hoặc NHƯ nhanh hơn trong Oracle?
- 12. Nhanh hơn asp.net mvc json hoặc json.net?
- 13. nhanh hơn? Bản Tuyên Bố hoặc PreparedStatement
- 14. nhanh hơn là gì?
- 15. Trong django, là tổng hợp (Count()) nhanh hơn hoặc tốt hơn .count() trong anyway?
- 16. khi nào java nhanh hơn C++ (hoặc khi nào JIT nhanh hơn được biên dịch trước)?
- 17. Ứng dụng 32 bit có chạy nhanh hơn hoặc chậm hơn trên hệ điều hành 64 bit không?
- 18. Tốc độ nào nhanh hơn, XPath hoặc Regexp?
- 19. Là + = nhanh hơn - =?
- 20. Còn lại THAM GIA nhanh hơn hoặc Tham gia bên trong nhanh hơn?
- 21. Đó là tốt hơn: mysql_connect hoặc mysql_pconnect
- 22. XPath hoặc Linq2Xml tốt hơn
- 23. Điều gì sẽ nhanh hơn: JDBC hoặc JNDI?
- 24. ASP.NET MVC hoặc Ruby On Rails nhanh hơn
- 25. Tại sao giảm nhanh hơn tổng hoặc sumBy?
- 26. i ++ hoặC++ hiệu quả hơn là gì?
- 27. những gì nhanh hơn: tạo lại hoặc xóa()?
- 28. Tốc độ nào nhanh hơn, EXISTS trước hoặc sau INSERT?
- 29. Vòng lặp nào nhanh hơn, trong khi hoặc cho?
- 30. Vẽ bitmap nhanh hơn trên canvas Android hoặc OpenGL
Cách dễ nhất để biết là dùng thử. Gói cả hai cuộc gọi đến các phương thức thích hợp trên StopWatch, thực hiện nó vài triệu lần và bạn sẽ biết. –
Nó có thể không có giá trị gì mà sẽ không có một sự khác biệt đáng chú ý về tốc độ trừ khi chúng ta đang nói về một số bộ sưu tập nghiêm túc lớn. Chỉ cần sử dụng cái nào dễ đọc/duy trì hơn. – Hardwareguy