以下代码提供了两种生成总和小于100的整数对的方法,它们根据它们与(0,0)的距离按降序排列。
//approach 1
private static IEnumerable<Tuple<int,int>> ProduceIndices3()
{
var storage = new List<Tuple<int, int>>();
for (int x = 0; x < 100; x++)
{
for (int y = 0; y < 100; y++)
{
if (x + y < 100)
storage.Add(Tuple.Create(x, y));
}
}
storage.Sort((p1,p2) =>
(p2.Item1 * p2.Item1 +
p2.Item2 * p2.Item2).CompareTo(
p1.Item1 * p1.Item1 +
p1.Item2 * p1.Item2));
return storage;
}
//approach 2
private static IEnumerable<Tuple<int, int>> QueryIndices3()
{
return from x in Enumerable.Range(0, 100)
from y in Enumerable.Range(0, 100)
where x + y < 100
orderby (x * x + y * y) descending
select Tuple.Create(x, y);
}
此代码取自Bill Wagner,第8项中的 Effective C#一书。在整篇文章中,作者更多地关注代码的语法,紧凑性和可读性,但很少注意表现,几乎没有讨论它。
所以我基本上想知道,哪种方法更快?性能通常更好(通常):查询语法或手动循环?
请详细讨论,如有提供参考。 : - )
答案 0 :(得分:9)
剖析是事实,但我的直觉是循环可能更快。重要的是99次中的100次性能差异在宏观方案中无关紧要。使用更易阅读的版本,以后您将需要在以后维护它时感谢您。
答案 1 :(得分:4)
运行每个功能1000次:
for循环:2623 ms 查询:2821毫秒
看起来很逻辑,因为第二个只是第一个的语法糖。但我会使用第二个来说明它的可读性。
答案 2 :(得分:1)
虽然这并没有严格回答你的问题,但是我会建议将x + y逻辑合并到迭代中,因此:
for (int x = 0; x < 100; x++)
for (int y = 0; y < 100 - x; y++)
storage.Add(Tuple.Create(x, y));