Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

string.IndexOf(string) poor performance in other cultures #96221

Closed
bennil opened this issue Dec 20, 2023 · 2 comments
Closed

string.IndexOf(string) poor performance in other cultures #96221

bennil opened this issue Dec 20, 2023 · 2 comments
Labels
Milestone

Comments

@bennil
Copy link

bennil commented Dec 20, 2023

Description

After migrating an old .NET Framework 4.7.2 windows app to .NET 8.0 I was suprised by it's poor performance.
I traced it down to an 11x times slower string.IndexOf(string) call on a large string (500 kilobyte).

But this happens only if the current culture is set other than English/Invariant.

Benchmark running in German culture context


BenchmarkDotNet v0.13.11, Windows 11 (10.0.22621.2861/22H2/2022Update/SunValley2)
Intel Core i7-8650U CPU 1.90GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
  [Host]               : .NET Framework 4.8.1 (4.8.9181.0), X64 RyuJIT VectorSize=256
  .NET 5.0             : .NET 5.0.7 (5.0.721.25508), X64 RyuJIT AVX2
  .NET 8.0             : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
  .NET Framework 4.7.2 : .NET Framework 4.8.1 (4.8.9181.0), X64 RyuJIT VectorSize=256


Method Job Runtime Mean Error StdDev Ratio RatioSD
IndexOfOfNotContainingStringInLargeString .NET 5.0 .NET 5.0 20.210 ms 0.3075 ms 0.2877 ms 12.79 0.16
IndexOfOfNotContainingStringInLargeString .NET 8.0 .NET 8.0 17.440 ms 0.2713 ms 0.2538 ms 11.04 0.15
IndexOfOfNotContainingStringInLargeString .NET Framework 4.7.2 .NET Framework 4.7.2 1.578 ms 0.0098 ms 0.0087 ms 1.00 0.00

Benchmark running in US culture context (perf as expected)

Method Job Runtime Mean Error StdDev Ratio RatioSD
IndexOfOfNotContainingStringInLargeString .NET 5.0 .NET 5.0 1,133.2 μs 7.46 μs 6.98 μs 0.71 0.02
IndexOfOfNotContainingStringInLargeString .NET 8.0 .NET 8.0 789.0 μs 3.95 μs 3.30 μs 0.50 0.01
IndexOfOfNotContainingStringInLargeString .NET Framework 4.7.2 .NET Framework 4.7.2 1,587.1 μs 31.59 μs 31.03 μs 1.00 0.00

Reproduce

BenchmarkDotNet StringIndexOfFrameworkPerfTest repo

You can easily switch the culture context in the BenchmarkDotNet setup method.

@bennil bennil added the tenet-performance Performance related issue label Dec 20, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Dec 20, 2023
@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Dec 20, 2023
@EgorBo EgorBo added area-System.Globalization and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Dec 20, 2023
@ghost
Copy link

ghost commented Dec 20, 2023

Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

After migrating an old .NET Framework 4.7.2 windows app to .NET 8.0 I was suprised by it's poor performance.
I traced it down to an 11x times slower string.IndexOf(string) call on a large string (500 kilobyte).

But this happens only if the current culture is set other than English/Invariant.

Benchmark running in German culture context


BenchmarkDotNet v0.13.11, Windows 11 (10.0.22621.2861/22H2/2022Update/SunValley2)
Intel Core i7-8650U CPU 1.90GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
  [Host]               : .NET Framework 4.8.1 (4.8.9181.0), X64 RyuJIT VectorSize=256
  .NET 5.0             : .NET 5.0.7 (5.0.721.25508), X64 RyuJIT AVX2
  .NET 8.0             : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
  .NET Framework 4.7.2 : .NET Framework 4.8.1 (4.8.9181.0), X64 RyuJIT VectorSize=256


Method Job Runtime Mean Error StdDev Ratio RatioSD
IndexOfOfNotContainingStringInLargeString .NET 5.0 .NET 5.0 20.210 ms 0.3075 ms 0.2877 ms 12.79 0.16
IndexOfOfNotContainingStringInLargeString .NET 8.0 .NET 8.0 17.440 ms 0.2713 ms 0.2538 ms 11.04 0.15
IndexOfOfNotContainingStringInLargeString .NET Framework 4.7.2 .NET Framework 4.7.2 1.578 ms 0.0098 ms 0.0087 ms 1.00 0.00

Benchmark running in US culture context (perf as expected)

Method Job Runtime Mean Error StdDev Ratio RatioSD
IndexOfOfNotContainingStringInLargeString .NET 5.0 .NET 5.0 1,133.2 μs 7.46 μs 6.98 μs 0.71 0.02
IndexOfOfNotContainingStringInLargeString .NET 8.0 .NET 8.0 789.0 μs 3.95 μs 3.30 μs 0.50 0.01
IndexOfOfNotContainingStringInLargeString .NET Framework 4.7.2 .NET Framework 4.7.2 1,587.1 μs 31.59 μs 31.03 μs 1.00 0.00

Reproduce

BenchmarkDotNet StringIndexOfFrameworkPerfTest repo

You can easily switch the culture context in the BenchmarkDotNet setup method.

Author: bennil
Assignees: -
Labels:

area-System.Globalization, tenet-performance, untriaged

Milestone: -

@tarekgh tarekgh added this to the Future milestone Dec 24, 2023
@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Dec 24, 2023
@tarekgh
Copy link
Member

tarekgh commented Dec 24, 2023

This is tracked by #40942

@tarekgh tarekgh closed this as completed Dec 24, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants