Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is ToUpperInvariant() faster than ToLowerInvariant()?

I read in CLR via C# by Jeffrey Richter that String.ToUpperInvariant() is faster than String.ToLowerInvariant(). He says that this is because the FCL uses ToUpperInvariant to normalise strings, so the method is ultra-optimised. Running a couple quick tests on my machine, I concur that ToUpperInvariant() is indeed slightly faster.

My question is if anybody knows how the function is actually optimised on a technical level, and/or why the same optimisations were not applied to ToLowerInvariant() as well.


Concerning the "duplicate": The proposed "duplicate" question really doesn't provide an answer to my question. I understand the benefits of using ToUpperInvariant instead of ToLowerInvariant, but what I would like to know is how/why ToUpperInvariant performs better. This point is not addressed in the "duplicate".

like image 916
Levi Botelho Avatar asked Sep 06 '13 12:09

Levi Botelho


People also ask

Is ToUpper faster than ToLower?

The other three are mostly the same. But in general, ToLowerInvariant is fastest, then ToUpper and then ToUpperInvariant . Surprisingly, the . NET Core is roughly 2,6× faster across the results.

What is the difference between ToLower and ToLowerInvariant?

ToLower() uses the default culture while String. ToLowerInvariant() uses the invariant culture.

What is ToUpperInvariant?

The ToUpperInvariant method is equivalent to ToUpper(CultureInfo. InvariantCulture) . The method is recommended when a collection of strings must appear in a predictable order in a user interface control. This method does not modify the value of the current instance.

What is ToLowerInvariant C#?

ToLowerInvariant() method in C# is used to return a copy of this String object converted to lowercase using the casing rules of the invariant culture.


1 Answers

Since it is now easier to read the CLR source which implements InternalChangeCaseString, we can see that it mostly calls down to the Win32 function LCMapStringEx. There appears to be no notes or any discussion on the performance of passing in LCMAP_UPPERCASE vs. LCMAP_LOWERCASE for the dwMapFlags parameter. Calling InternalChangeCaseString uses a flag isToUpper which, if true may result in better optimization by the compiler (or JITter), but since the call to LCMapStringEx has to setup a p/invoke call frame and the call itself has to do work, I'm not sure a lot of time is saved there.

Perhaps the recommendation is a hold over from some other implementation, but I can't see anything that would provide a significant speed advantage one way or the other.

like image 156
codekaizen Avatar answered Sep 29 '22 14:09

codekaizen