I am in the process of creating a service to make it easy for a user to select a protocol from the IANA - Protocol Registry.
As you might imagine searching the registry for the term http
pulls up a lot of hits. Since amt-soap-http
is going to selected by a user much less frequently than straight http
I decided that it would be a good idea to pull out everything that starts with http
and then concatenate that with the remaining results.
The below lambda expression is the result of that thought process:
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);
Unfortunately, I feel like I am iterating through my results more times than necessary. Premature optimization considerations aside is there a combination of lambda expressions that would be more efficient than the above?
It might be more efficient as a two-step ordering:
var results = records.OrderBy(r => r.Name.StartsWith(term) ? 1 : 2)
.ThenBy(r => r.Name)
.Take(MaxResultSize);
Using comment to explain what I am trying to do is getting hard. So i will post this another answer.
Suppose I want to sort a list of random integers first according to its being even or odd then in numerical order (simulating StartsWith
with mod 2
).
Here is the test case: action2 is the same as other answer.
If you run this code you will see that my suggestion (action1
) is two times faster.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With