[ACCEPTED]-Fastest way to count number of uppercase characters in c#-linq

Accepted answer
Score: 39

Ok, just knocked up some code to time your 6 method against this:

int count = 0;
for (int i = 0; i < s.Length; i++)
{
    if (char.IsUpper(s[i])) count++;
}

The result:

Yours: 19737 5 ticks

Mine: 118 ticks

Pretty big difference! Sometimes 4 the most straight-forward way is the most 3 efficient.

Edit

Just out of interest, this:

int count = s.Count(c => char.IsUpper(c));

Comes 2 in at at around 2500 ticks. So for a "Linqy" one-liner 1 it's pretty quick.

Score: 7

First there is no reason you need to call 11 ToCharArray() since, assuming CommentText is a string it is already 10 an IEnumerable<char>. Second, you should probably be calling 9 char.IsUpper instead of assuming you are only dealing 8 with ASCII values. The code should really 7 look like,

CommentText.Count(char.IsUpper)

Third, if you are worried about 6 speed there isn't much that can beat the 5 old for loop,

int count = 0;
for (int i = 0; i < CommentText.Length; i++) 
   if (char.IsUpper(CommentText[i]) count++;

In general, calling any method 4 is going to be slower than inlining the 3 code but this kind of optimization should 2 only be done if you are absolutely sure 1 this is the bottle-neck in your code.

Score: 4

You're only counting standard ASCII and 1 not ÃÐÊ etc.

How about

CommentText.ToCharArray().Where(c => Char.IsUpper(c)).Count()
Score: 4

Without even testing I'd say

int count = 0;
foreach (char c in commentText)
{
    if (Char.IsUpper(c))
        count++;
}

is faster, off 1 now to test it.

Score: 3

What you are doing with that code is to 8 create a collection with the characters, then 7 create a new collection containing only 6 the uppercase characters, then loop through 5 that collection only to find out how many 4 there are.

This will perform better (but 3 still not quite as good as a plain loop), as 2 it doesn't create the intermediate collections:

CommentText.Count(c => Char.IsUpper(c))

Edit: Removed 1 the ToCharArray call also, as Matt suggested.

Score: 2

I've got this

Regex x = new Regex("[A-Z]{1}", 
  RegexOptions.Compiled | RegexOptions.CultureInvariant);
int c = x.Matches(s).Count;

but I don't know if its particularly quick. It won't get special chars either, I s'pose

EDIT:

Quick comparison to this question's 2 answer. Debug in vshost, 10'000 iterations 1 with the string:
aBcDeFGHi1287jKK6437628asghwHllmTbynerA

  • The answer: 20-30 ms
  • The regex solution: 140-170 ms

More Related questions