我先运行以下代码:
var stringList = new[]{"A","BB","CCC","DDDD"};
var dictionary = new Dictionary<int, string>();
var stopwatch = new Stopwatch();
stopwatch.Start();
foreach (var s in stringList)
{
dictionary.Add(s.Length,s);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);
Console.ReadKey();
执行时间为:00:00:00.0000205
然后我运行了以下代码......
var stringList = new[]{"A","BB","CCC","DDDD"};
var stopwatch = new Stopwatch();
stopwatch.Start();
var dictionary = stringList.ToDictionary(s => s.Length);
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed);
Console.ReadKey();
执行时间为:00:00:00.0037431
这是否证明foreach比LINQ更好?
答案 0 :(得分:2)
它是否证明foreach比LINQ更好?
不,它证明它更快。
更好的是主观概念。例如,如果您希望拥有更具可读性和紧凑性的代码,并且性能不是项目的最高优先级,并且已经确定这不是瓶颈,那么LINQ实际上可能会更好。
答案 1 :(得分:2)
您的示例有几个问题:
你应该看看Jon Skeet关于这个主题的blog post
答案 2 :(得分:2)
您可以看到使用.NET源或ILSpy ToDictionary
的真实外观:
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (keySelector == null)
{
throw Error.ArgumentNull("keySelector");
}
if (elementSelector == null)
{
throw Error.ArgumentNull("elementSelector");
}
Dictionary<TKey, TElement> dictionary = new Dictionary<TKey, TElement>(comparer);
foreach (TSource current in source)
{
dictionary.Add(keySelector(current), elementSelector(current));
}
return dictionary;
}
如您所见,它也使用foreach
!但是,通过Func
方法调用,参数检查和Dictionary.Add
代理的效率会比自定义代码低一点。但是,我认为在实际应用中使用ToDictionary
而不是自定义foreach
的惩罚并不重要。
答案 3 :(得分:0)
为什么?
因为没有魔法,LINQ版本比非LINQ版本做了很多处理。
我写了一小段代码,展示了LINQ在内部的作用。你可以看到几乎相同的表演。另外请注意我在循环中添加了字典的实例化:
int testCount = 1000000;
var stringList = new[] { "A", "BB", "CCC", "DDDD" };
Func<string, string> elementSelector = (value) => value;
var stopwatch = Stopwatch.StartNew();
for (int i = 0; i < testCount; i++)
{
var dictionary = new Dictionary<int, string>();
Func<string, int> keySelector = (value) => value.Length;
foreach (var s in stringList)
{
if (keySelector != null && elementSelector != null)
{
dictionary.Add(keySelector(s), elementSelector(s));
}
}
}
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed.TotalMilliseconds / testCount);
var stopwatch2 = Stopwatch.StartNew();
for (int i = 0; i < testCount; i++)
{
var dictionary2 = stringList.ToDictionary(s => s.Length);
}
stopwatch2.Stop();
Console.WriteLine(stopwatch2.Elapsed.TotalMilliseconds / testCount);
Console.ReadKey();