Skip to content

Conversation

@GrabYourPitchforks
Copy link
Member

Somewhat inspired by Steve's PR at #35185. Turns out we call char.ToUpperInvariant / char.ToLowerInvariant in a few dozen places within the runtime.

This PR improves these code paths by: (a) not bouncing through the TextInfo.Invariant indirection for ASCII data or when GlobalizationMode.Invariant is enabled; (b) inlining small methods that the JIT wasn't already inlining; and (c) tweaking the bit twiddling to get more efficient codegen.

Method Toolchain args Mean Error StdDev Ratio Code Size
CharToUpperInvariant master Hello World! 51.98 ns 0.615 ns 0.545 ns 1.00 147 B
CharToUpperInvariant textinfo Hello World! 22.71 ns 0.436 ns 0.408 ns 0.44 105 B
CharToLowerInvariant master Hello World! 49.15 ns 0.295 ns 0.247 ns 1.00 144 B
CharToLowerInvariant textinfo Hello World! 22.68 ns 0.242 ns 0.215 ns 0.46 105 B
[Benchmark]
[Arguments("Hello World!")]
public int CharToUpperInvariant(string args)
{
    int accum = 0;
    for (int i = 0; i < args.Length; i++)
    {
        accum += char.ToUpperInvariant(args[i]);
    }
    return accum;
}

[Benchmark]
[Arguments("Hello World!")]
public int CharToLowerInvariant(string args)
{
    int accum = 0;
    for (int i = 0; i < args.Length; i++)
    {
        accum += char.ToLowerInvariant(args[i]);
    }
    return accum;
}

@GrabYourPitchforks
Copy link
Member Author

I also tried testing a branchless implementation but the results were about the same for the different inputs I tried. So no need to complicate the logic.

@gfoidl
Copy link
Member

gfoidl commented Apr 20, 2020

Should the above benchmarks be added to dotnet/performance?
For string there are benchmarks for ToUpperInvariant, but not for char.

@GrabYourPitchforks
Copy link
Member Author

Good catch @gfoidl on the benchmarks repo! I'll get that PR up before closing this out.

@GrabYourPitchforks GrabYourPitchforks merged commit 87f78fe into dotnet:master Apr 20, 2020
@GrabYourPitchforks GrabYourPitchforks deleted the invariant_perf branch April 20, 2020 19:06
@ghost ghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants