5

ユーザーがIANA-Protocol Registryからプロトコルを簡単に選択できるようにするサービスを作成中です。

ご想像のとおり、レジストリで用語を検索するとhttp、多くのヒットが表示されます。amt-soap-httpユーザーが を選択する頻度はストレートよりもはるかに少ないのでhttp、 で始まるものをすべて取り出してhttp、それを残りの結果と連結することをお勧めします。

以下のラムダ式は、その思考プロセスの結果です。

var records = this._ianaRegistryService.GetAllLike(term).ToList();
var results = records.Where(r => r.Name.StartsWith(term))
                     .OrderBy(r => r.Name)
                     .Concat(records.Where(r => !r.Name.StartsWith(term))
                                    .OrderBy(r => r.Name))
                     .Take(MaxResultSize);

残念ながら、必要以上に結果を反復しているように感じます。時期尚早の最適化に関する考慮事項はさておき、上記よりも効率的なラムダ式の組み合わせはありますか?

4

2 に答える 2

5

2段階の順序付けの方が効率的かもしれません:

var results = records.OrderBy(r => r.Name.StartsWith(term) ? 1 : 2)
                     .ThenBy(r => r.Name)
                     .Take(MaxResultSize);
于 2013-02-14T21:32:45.663 に答える
3

私がやろうとしていることを説明するためにコメントを使用するのは難しくなっています。だから私はこの別の答えを投稿します。ランダムな整数のリストを最初に偶数または奇数に従って並べ替え、次に番号順に並べ替えたいとします( でシミュレートStartsWithmod 2ます)。

テストケースは次のとおりです。action2は他の回答と同じです。

このコードを実行すると、私の提案 ( action1) が 2 倍高速であることがわかります。

void Test()
{
    Random rnd = new Random();
    List<int> records = new List<int>();
    for(int i=0;i<2000000;i++)
    {
        records.Add(rnd.Next());
    }

    Action action1 = () =>
    {
        var res1 = records.GroupBy(r => r % 2)
                    .OrderBy(x => x.Key)
                    .Select(x => x.OrderBy(y => y))
                    .SelectMany(x => x)
                    .ToList();
    };

    Action action2 = () =>
    {
        var res2 = records.OrderBy(x => x % 2).ThenBy(x => x).ToList();
    };


    //Avoid counting JIT
    action1();
    action2();


    var sw = Stopwatch.StartNew();
    action1();
    long t1 = sw.ElapsedMilliseconds;

    sw.Restart();
    action2();
    long t2 = sw.ElapsedMilliseconds;

    Console.WriteLine(t1 + " " + t2);
}
于 2013-02-15T18:25:08.457 に答える