我做了一个递归查找符合条件的第一个或默认项目(第一个代码块)的函数。此LINQ性能来自哪里?
Resharper建议我只在一条LINQ行(第二个代码块)中更改几行。
我想知道如果Resharper的建议会给我相同的性能和相同的内存占用。我对性能进行了测试(第3代码块)。结果就是我所期望的。为什么差异如此之大?
8156 milliseconds
Laure
23567 milliseconds
Laure LINQ
从哪里来的差异???为什么结果不一样?......或者至少更接近?
public static T RecursiveFirstOrDefault<T>(this T item, Func<T, IEnumerable<T>> childrenSelector, Predicate<T> condition)
where T : class // Hierarchy implies class. Don't need to play with "default()" here.
{
if (item == null)
{
return null;
}
if (condition(item))
{
return item;
}
foreach (T child in childrenSelector(item))
{
T result = child.RecursiveFirstOrDefault(childrenSelector, condition);
if (result != null)
{
return result;
}
}
return null;
}
但ReSharper的建议我在foreach块转换为LINQ查询如下:
public static T RecursiveFirstOrDefaultLinq<T>(this T item, Func<T, IEnumerable<T>> childrenSelector, Predicate<T> condition)
where T : class // Hierarchy implies class. Don't need to play with "default()" here.
{
if (item == null)
{
return null;
}
if (condition(item))
{
return item;
}
// Resharper change:
return childrenSelector(item).Select(child => child.RecursiveFirstOrDefaultLinq(childrenSelector, condition)).FirstOrDefault(result => result != null);
}
测试:
private void ButtonTest_OnClick(object sender, RoutedEventArgs e)
{
VariationSet varSetResult;
Stopwatch watch = new Stopwatch();
varSetResult = null;
watch.Start();
for(int n = 0; n < 10000000; n++)
{
varSetResult = Model.VariationRef.VariationSet.RecursiveFirstOrDefault((varSet) => varSet.VariationSets,
(varSet) => varSet.Name.Contains("Laure"));
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds.ToString() + " milliseconds");
Console.WriteLine(varSetResult.Name);
watch.Reset();
varSetResult = null;
watch.Start();
for(int n = 0; n < 10000000; n++)
{
varSetResult = Model.VariationRef.VariationSet.RecursiveFirstOrDefaultLinq((varSet) => varSet.VariationSets,
(varSet) => varSet.Name.Contains("Laure"));
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds.ToString() + " milliseconds");
Console.WriteLine(varSetResult.Name + " LINQ");
}
我必须去...今天希望能正确回答测试:x86,在12核心机器上发布,Windows 7,Framework.Net 4.5,
我的结论:
在我的情况下,它是非linq版本的约3倍。在LINQ中,可读性更好,但是在图书馆中,只要记住它的功能和如何调用它(在这种情况下 - 不是绝对的一般情况)。 LINQ几乎总是比好的编码方法慢。 我会personnaly味:
- LINQ:如果性能是不是真的在 具体项目代码的问题(大多数情况下)
- 非LINQ的:在性能是具体项目的代码的问题,其中使用一个库和代码应该是稳定和固定的方法的使用应该有据可查,我们 不应该真的需要挖掘内部。
底层编译器编译的linq代码和foreach代码有很大不同,这就是你的区别所在。 – 2014-09-03 18:05:07
您是否必须重置计时器以获得第二次测试迭代的正确计数? – entropic 2014-09-03 18:05:41
@entropic,谢谢... :-(!!!!! – 2014-09-03 18:06:41