我已经检查了嵌套循环的不同性能。但是Distinct方法比嵌套循环快得多。
var customers = new List<Customer>();
for (var i = 1; i <= 100000; i++)
{
var id = (int)Math.Floor((decimal)i / 10);
var customer = new Customer()
{
FirstName = $"Name {i}",
ID = id,
LastName = $"Last {i}"
};
customers.Add(customer);
}
System.Console.WriteLine($"Outer Loop start :{DateTime.UtcNow}");
var ids = new List<int>();
customers.ForEach(_=> {
ids.Add(_.ID);
});
var uniqueIds = ids.Distinct();
System.Console.WriteLine($"Outer Loop End :{DateTime.UtcNow}");
System.Console.WriteLine($"Nested Loop start :{DateTime.UtcNow}");
var oids = new List<int>();
customers.ForEach(_ => {
if (!oids.Any(i => i == _.ID))
{
oids.Add(_.ID);
}
});
System.Console.WriteLine($"Nested Loop End :{DateTime.UtcNow}");
字符串
结果:外循环开始:2020/6/20 4:15:31 PM外循环结束:2020/6/20 4:15:31 PM嵌套循环开始:2020/6/20 4:15:32 PM嵌套循环结束:2020/6/20 4:15:46 PM
Outerloop只需要1秒,但嵌套循环需要14秒。在foreach中,Distinct比使用“Any”函数快多少?
1条答案
按热度按时间brccelvz1#
首先,它更快,因为
Distinct
实际上几乎什么都不做-uniqueIds
不是物化的IEnumerable<int>
(例如,您可以在ids
和.Distinct()
之间添加.Select(c => {Console.WriteLine(c);return c;})
),将uniqueIds
声明行更改为:字符串
其次,对于适当的基准测试,我建议使用BenchmarkDotNet,对于您的情况,您可以编写例如以下基准测试(删除/重组一些代码,因为它与实际基准测试的内容无关):
型
在我的机器上给出了下一个结果:
型
最后是“为什么”。
Distinct
在内部使用DistinctIterator
,而DistinctIterator
又使用内部的Set
类,描述为A lightweight hash set
,据我所知,在搜索Big-O复杂度方面应该与hashtable相当,在最佳/平均情况下导致constant search time,而List
的搜索(!oids.Any
)复杂度为O(n)。