4

次のコードは、合計が 100 未満の整数のペアを生成する 2 つのアプローチを提供し、それらは (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 から引用したものです。この記事全体で、著者はコードの構文、コンパクトさ、読みやすさに重点を置いていますが、パフォーマンスにはほとんど注意を払っていません。議論しなかった。

だから私は基本的に知りたいのですが、どちらのアプローチが速いですか? 通常、(一般的に) パフォーマンスが優れているのはどれですか: クエリ構文または手動ループ?

参考文献があれば、それらについて詳しく説明してください。:-)

4

3 に答える 3

9

プロファイリングは真実ですが、私の直感では、おそらくループの方が速いと思います。重要なことは、100 回中 99 回のパフォーマンスの違いは、大局的には問題にならないということです。より読みやすいバージョンを使用してください。後でそれを維持する必要があるときに、将来の自分が感謝するでしょう。

于 2011-01-20T19:28:41.490 に答える
4

各関数を 1000 回実行:

for ループ: 2623 ミリ秒 クエリ: 2821 ミリ秒

2番目のものは最初のものの構文糖衣であるため、ロジックに見えます。しかし、読みやすさのために2番目のものを使用します。

于 2011-01-20T19:46:57.027 に答える
1

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));
于 2011-01-20T19:33:20.373 に答える