如何有效地限制然后将结果与linq / lambda表达式连接起来?

时间:2013-02-14 21:23:11

标签: c# lambda concat

我正在创建服务,以便用户轻松选择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); 。剩下的结果。

以下lambda表达式是该思维过程的结果:

{{1}}

不幸的是,我觉得我在结果中迭代的时间超过了必要的次数。除了过早的优化考虑因素有一个lambda表达式的组合,它会比上面的更有效吗?

2 个答案:

答案 0 :(得分:5)

作为两步排序可能更有效:

var results = records.OrderBy(r => r.Name.StartsWith(term) ? 1 : 2)
                     .ThenBy(r => r.Name)
                     .Take(MaxResultSize);

答案 1 :(得分:3)

使用评论来解释我想要做的事情就是变得越来越难。所以我会发布另一个答案。 假设我想先按照偶数或奇数的顺序排序随机整数列表,然后按数字顺序排序(用StartsWith模拟mod 2)。

以下是测试用例: action2 与其他答案相同。

如果您运行此代码,您会看到我的建议(action1)快两倍。

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);
}