哪个更快:查询语法与循环
下面的代码提供了两种生成总和小于 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的Effective C#一书,第8条。在整篇文章中,作者更多地关注于代码的语法、紧凑性和可读性,但付出的代价却很少关注表演,几乎不讨论它。
所以我基本上想知道哪种方法更快?通常,什么在性能上更好:查询语法还是手动循环?
请详细讨论它们,如果有的话请提供参考。 :-)
The following code provides two approaches that generate pairs of integers whose sum is less than 100, and they're arranged in descending order based on their distance from (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);
}
This code is taken from the book Effective C# by Bill Wagner, Item 8. In the entire article, the author has focused more on the syntax, the compactness and the readability of the code, but paid very little attention to the performance, and almost didn't discuss it.
So I basically want to know, which approach is faster? And what is usually better at performance (in general) : Query Syntax or Manual Loops?
Please discuss them in detail, providing references if any. :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
分析是事实,但我的直觉是循环可能更快。重要的是,百分之九十九的性能差异在总体方案中并不重要。使用更具可读性的版本,当您以后需要维护它时,未来的您会感谢您。
Profiling is truth, but my gut feeling would be that the loops are probably faster. The important thing is that 99 times out of 100 the performance difference just doesn't matter in the grand scheme of things. Use the more readable version and your future self will thank you when you need to maintain it later.
运行每个函数 1000 次:
for 循环:2623 ms
query: 2821 ms
看起来很逻辑,因为第二个只是第一个的语法糖。但我会使用第二个,因为它的可读性。
Running each function 1000 times:
for loop: 2623 ms
query: 2821 ms
looks logic since the second one is just syntaxic sugar for the first one. But i would use the second one for its readability.
虽然这并不能严格回答您的问题,但从性能角度来看,我建议将 x+y 逻辑合并到迭代中,因此:
Though this doesn't strictly answer your question, performance-wise I would suggest merging that x+y logic into the iteration, thus: