2

I need to find the fastest way to get a small list of strings or chars in custom order. I found a lot of questions about sorting a list, but there is no question on the board or web about sorting a small list with a native type, all I found was way more complex.

For me it does not matter if my input list is a string list or char list. My list has 5 - 7 items, they look like this: "1","Q","A","8","9". I want to get my input ordered like this: "2", "3", "4", "5", "6", "7", "8", "9", "1", "J", "Q", "K", "A".

I tried the following codes:

1 = 3.1-3.5 milliseconds :

static readonly List<String> codeValueSortOrder = new List<String> 
{ 
    "2", "3", "4", "5", "6", "7", "8", "9", "1", "J", "Q", "K", "A" 
};
input.OrderBy(i => codeValueSortOrder.IndexOf(i.ToString())).ToList();

2 = 5.0-6.0 milliseconds:

input.OrderBy(i => i[1] == 'A')
     .ThenBy(i => i[1] == 'K')
     .ThenBy(i => i[1] == 'Q')
     .ThenBy(i => i[1] == 'J')
     .ThenBy(i => i.Substring(1, i.Length - 1) == "10")
     .ThenBy(i => i[1] == '9')
     .ThenBy(i => i[1] == '8')
     .ThenBy(i => i[1] == '7')
     .ThenBy(i => i[1] == '6')
     .ThenBy(i => i[1] == '5')
     .ThenBy(i => i[1] == '4')
     .ThenBy(i => i[1] == '3')
     .ThenBy(i => i[1] == '2')
     .ToList();

I also looked at a few projects at codeproject, but this codes are for million of items, I can´t imagine that they are the most efficient way if we just want to sort between 5 and 7 items. My goal is to perform the sorting in under 0.1 milliseonds, I have no idea if it is possible to accomplish that goal :)

6
  • 1
    Can you post your benchmarking code.? Commented Aug 28, 2014 at 10:17
  • are these always going to be the same 7 values? if so then you can probably just initialize the array with the values in the desired order Commented Aug 28, 2014 at 10:17
  • can the items repeat or not? and @Sayse: op wants to sort between 5 and 7 items, i take it they're random. Commented Aug 28, 2014 at 10:47
  • Yes the items will repeat a few times, up to 4 duplicates. And they are something like random. Commented Aug 28, 2014 at 10:52
  • Regardless of performance I wouldn't use the 2nd approach. Maintenance nightmare. Commented Aug 28, 2014 at 11:31

2 Answers 2

5

You could use a Dictionary<string, int> where the key is the string and the value is the index.

You can even still use the List<string> as basis:

private static readonly List<string> _List = new List<string> { "2", "3", "4", "5", "6", "7", "8", "9", "1", "J", "Q", "K", "A" };
static readonly Dictionary<string, int> Order = _List
    .ToDictionary(str => str, str => _List.IndexOf(str) + 1);

Now you're able to use List.Sort which does not need to create a new list as the LINQ approaches:

var input = new List<string> { "1", "Q", "A", "8", "9" };
int i1, i2;
input.Sort((s1, s2) =>
{
    Order.TryGetValue(s1, out i1);
    Order.TryGetValue(s2, out i2);
    return i1.CompareTo(i2);
});

Result order: 8,9,1,Q,A

A quick test revealed: StopWatch.Elapsed.TotalMilliseconds 0.0045

Dictionary.TryGetValue returns either the index if the string was found or 0 otherwise. That's why i've used _List.IndexOf(str) + 1 above to force that found items come last.

If you want a descending order you just have to reverse it:

return i2.CompareTo(i1);
Sign up to request clarification or add additional context in comments.

3 Comments

Add 1 to your IndexOf and you can skip the ternary (although then you don't get to confuse people by declaring i1 and using it as an out parameter in the same line).
@Rawling: point taken. Although now it's more difficult to change the order if the non-found items should come last.
Yeah, that's a fair point. It might not even make a noticable difference to the time.
1

if you are trying to write high performant poker code you really need to get rid of string/char representations and stick to int 0-12 values for deuces-aces

You say that your input is strings/chars, but its rare to find a place in high performant poker code where input is really char/string.

If you are trying to parse text boards and figuring out the hands of players performance is not so important usually.

If you are making some exhaustive board combinatorics you really need to stick to ints.

1 Comment

When you would do what I do, then you would realize that the difference is not that huge, but I will test it with int later, just to be sure ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.