哪个更快:查询语法与循环

发布于 2024-10-13 05:40:05 字数 1209 浏览 4 评论 0原文

下面的代码提供了两种生成总和小于 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不弃不离 2024-10-20 05:40:05

分析是事实,但我的直觉是循环可能更快。重要的是,百分之九十九的性能差异在总体方案中并不重要。使用更具可读性的版本,当您以后需要维护它时,未来的您会感谢您。

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.

¢蛋碎的人ぎ生 2024-10-20 05:40:05

运行每个函数 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.

陌伤浅笑 2024-10-20 05:40:05

虽然这并不能严格回答您的问题,但从性能角度来看,我建议将 x+y 逻辑合并到迭代中,因此:

for (int x = 0; x < 100; x++)
    for (int y = 0; y < 100 - x; y++)
        storage.Add(Tuple.Create(x, y));

Though this doesn't strictly answer your question, performance-wise I would suggest merging that x+y logic into the iteration, thus:

for (int x = 0; x < 100; x++)
    for (int y = 0; y < 100 - x; y++)
        storage.Add(Tuple.Create(x, y));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文