我正在创建服务,以便用户轻松选择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表达式的组合,它会比上面的更有效吗?
答案 0 :(得分:5)
作为两步排序可能更有效:
var results = records.OrderBy(r => r.Name.StartsWith(term) ? 1 : 2)
.ThenBy(r => r.Name)
.Take(MaxResultSize);
答案 1 :(得分:3)
使用评论来解释我想要做的事情就是变得越来越难。所以我会发布另一个答案。
假设我想先按照偶数或奇数的顺序排序随机整数列表,然后按数字顺序排序(用StartsWith
模拟mod 2
)。
以下是测试用例:
如果您运行此代码,您会看到我的建议(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);
}