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".
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.
ToLower() uses the default culture while String. ToLowerInvariant() uses the invariant culture.
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.
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.
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.
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