Skip to content

Unexpectedly high latency of string utility functions on Linux (about 3 times higher than the same function on windows) #37919

@dmeytin

Description

@dmeytin

Issue Title

Unexpected latency of string utility functions on Linux

General

I have used https://github.com/dotnet/BenchmarkDotNet to test String.IndexOf on Windows and on Linux and the results below reveal almost 3 times latency difference for the function invocation on the random string of sizes 200 ... 1000, small constant pattern of the size 4 and OrdinalIgnoreCase culture

Latency of 1K executions are as following:
Linux: Avg : 3.151195819999976ms; Mean: 3.0258999999999796ms; Percentile_95: 3.8338250000000005ms
Windows: Avg : 1.136806029999999ms; Mean: 1.0643499999999961ms; Percentile_95: 1.5009250000000038ms

Here is the benchmark code:


public class StringUtils
    {
        string randomString;
        string toSearch = " -p ";
        char[] pattern;

        [Params(200, 300, 400, 500, 600, 700, 800, 900, 1000)]
        public int N;

        public StringUtils()
        {
            pattern = toSearch.ToLower().ToCharArray();
        }

        [IterationSetup]
        public void BeforeEachStep()
        {
            randomString = GenerateRandomString(N);
        }
        
        [Benchmark]
        public void IndexOf()
        {
            randomString.IndexOf(toSearch, StringComparison.OrdinalIgnoreCase);
        } 

        private string GenerateRandomString(int length)
        {
            Random random = new Random();
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 -abcdefghijklmnopqrstuvwxyz!#@";
            return new string(Enumerable.Repeat(chars, length)
              .Select(s => s[random.Next(s.Length)]).ToArray());
        }
    }

Although both VMs are created with the same Azure SKU (Standard_D2s_v3), the actual hardware is a bit different, but not significantly.

BenchmarkDotNet=v0.12.1, OS=ubuntu 18.04
Intel Xeon CPU E5-2673 v4 2.30GHz, 1 CPU, 2 logical cores and 1 physical core
.NET Core SDK=3.1.301
[Host] : .NET Core 3.1.5 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.27001), X64 RyuJIT
Job-YVSZZG : .NET Core 3.1.5 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.27001), X64 RyuJIT

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.14393.3750 (1607/AnniversaryUpdate/Redstone1)
Intel Xeon Platinum 8171M CPU 2.60GHz, 1 CPU, 2 logical cores and 1 physical core
.NET Core SDK=3.1.301
[Host] : .NET Core 3.1.5 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.27001), X64 RyuJIT
Job-BSDYRT : .NET Core 3.1.5 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.27001), X64 RyuJIT

InvocationCount=1 UnrollFactor=1

And detailed results are as following:

OS Method N Mean Error StdDev Median
Linux IndexOf 200 5.329 us 0.1135 us 0.3145 us 5.300 us
Windows IndexOf 200 3.159 us 0.1491 us 0.4303 us 3.200 us
Linux IndexOf 300 7.700 us 0.1570 us 0.1927 us 7.700 us
Windows IndexOf 300 4.096 us 0.1676 us 0.4915 us 4.100 us
Linux IndexOf 400 8.800 us 0.1714 us 0.1519 us 8.800 us
Windows IndexOf 400 4.886 us 0.2148 us 0.6334 us 5.050 us
Linux IndexOf 500 11.604 us 0.3069 us 0.8192 us 11.500 us
Windows IndexOf 500 5.679 us 0.2132 us 0.6220 us 5.650 us
Linux IndexOf 600 12.933 us 0.2662 us 0.7107 us 12.601 us
Windows IndexOf 600 6.604 us 0.2407 us 0.7058 us 6.700 us
Linux IndexOf 700 14.443 us 0.2824 us 0.2504 us 14.450 us
Windows IndexOf 700 7.204 us 0.1426 us 0.2045 us 7.100 us
Linux IndexOf 800 17.629 us 0.3564 us 0.9575 us 17.500 us
Windows IndexOf 800 8.074 us 0.3290 us 0.9385 us 8.200 us
Linux IndexOf 900 19.018 us 0.5516 us 1.5194 us 18.700 us
Windows IndexOf 900 8.852 us 0.3884 us 1.1328 us 9.050 us
Linux IndexOf 1000 20.609 us 0.4151 us 0.8194 us 20.350 us
Windows IndexOf 1000 9.607 us 0.3468 us 1.0060 us 9.700 us

#Expected results
Linux latency should be at least as good as Windows

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions