Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Replace char[] array in CompletionRequiresQuotes with cached SearchValues<char>#24907

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation

ArmaanMcleod
Copy link
Contributor

@ArmaanMcleodArmaanMcleod commentedJan 31, 2025
edited
Loading

PR Summary

Similar to below PRs:

#24896
#24880
#24879

I've removed thechar[] array allocation inCompletionRequiresQuotes to reduce allocations every time this method is called which is referenced in 15 different places inCompletionCompleters class.

Instead I have made the default chars & escape chars of typeSearchValues<char> which is cached in the class and use a methodContainsCharsToCheck. This method replaces the previousIndexOfAny calls with thechar[] array and instead uses the efficient ContainsAny<T>(Span<T>, SearchValues<T>)).

I have done some benchmarks and it seems to bring a performance benefit with execution count and reduced allocation.

Benchmark

Details

Test Code

usingSystem.Buffers;usingSystem.Text;usingBenchmarkDotNet.Attributes;usingBenchmarkDotNet.Configs;usingBenchmarkDotNet.Order;usingBenchmarkDotNet.Running;namespaceBenchMark;[MemoryDiagnoser][RankColumn][Orderer(SummaryOrderPolicy.FastestToSlowest)][GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByParams)]publicclassSearchValuesBenchmark2{publicstaticreadonlyList<string>Strings=[];privatestaticreadonlySearchValues<char>s_defaultCharsToCheck=SearchValues.Create("$`");privatestaticreadonlySearchValues<char>s_escapeCharsToCheck=SearchValues.Create("$[]`");privatestaticboolContainsCharsToCheck(ReadOnlySpan<char>text,boolescape)=>text.ContainsAny(escape?s_escapeCharsToCheck:s_defaultCharsToCheck);[Params(10,100,1000)]publicintStringCount;privateclassRandomGenerator{privatestaticreadonlyRandomrandom=new();privateconststringchars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789$[]`";publicstaticstringGenerateRandomTextWithSpecialChars(intminLength,intmaxLength){intlength=random.Next(minLength,maxLength+1);varstringBuilder=newStringBuilder(length);for(inti=0;i<length;i++){stringBuilder.Append(chars[random.Next(chars.Length)]);}returnstringBuilder.ToString();}publicstaticboolGetRandomBool()=>random.Next(2)==1;}[GlobalSetup]publicvoidSetup(){for(inti=0;i<StringCount;i++){Strings.Add(RandomGenerator.GenerateRandomTextWithSpecialChars(10,100));}}[Benchmark(Baseline=true)]publicintWithIndexofAnyAndCharArray(){intcheckCount=0;foreach(varstrinStrings){varescape=RandomGenerator.GetRandomBool();char[]charToCheck=escape?['$','[',']','`']:['$','`'];if(str.IndexOfAny(charToCheck)!=1){checkCount++;}}returncheckCount;}[Benchmark]publicintWithSearchValuesContains(){intcheckCount=0;foreach(varstrinStrings){varescape=RandomGenerator.GetRandomBool();if(ContainsCharsToCheck(str,escape)){checkCount++;}}returncheckCount;}}publicclassProgram{publicstaticvoidMain(string[]args){BenchmarkRunner.Run<SearchValuesBenchmark2>();}}

Results

// * Detailed results *SearchValuesBenchmark2.WithSearchValuesContains: DefaultJob [StringCount=10]Runtime = .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2; GC = Concurrent WorkstationMean = 116.001 ns, StdErr = 0.096 ns (0.08%), N = 15, StdDev = 0.374 nsMin = 115.315 ns, Q1 = 115.717 ns, Median = 116.086 ns, Q3 = 116.240 ns, Max = 116.490 nsIQR = 0.523 ns, LowerFence = 114.931 ns, UpperFence = 117.025 nsConfidenceInterval = [115.601 ns; 116.400 ns] (CI 99.9%), Margin = 0.399 ns (0.34% of Mean)Skewness = -0.47, Kurtosis = 1.75, MValue = 2-------------------- Histogram --------------------[115.116 ns ; 116.689 ns) | @@@@@@@@@@@@@@@---------------------------------------------------SearchValuesBenchmark2.WithIndexofAnyAndCharArray: DefaultJob [StringCount=10]Runtime = .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2; GC = Concurrent WorkstationMean = 165.199 ns, StdErr = 0.465 ns (0.28%), N = 14, StdDev = 1.741 nsMin = 161.502 ns, Q1 = 164.679 ns, Median = 165.128 ns, Q3 = 166.057 ns, Max = 168.138 nsIQR = 1.378 ns, LowerFence = 162.612 ns, UpperFence = 168.124 nsConfidenceInterval = [163.235 ns; 167.163 ns] (CI 99.9%), Margin = 1.964 ns (1.19% of Mean)Skewness = -0.37, Kurtosis = 2.59, MValue = 2-------------------- Histogram --------------------[160.554 ns ; 169.086 ns) | @@@@@@@@@@@@@@---------------------------------------------------SearchValuesBenchmark2.WithSearchValuesContains: DefaultJob [StringCount=100]Runtime = .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2; GC = Concurrent WorkstationMean = 1.401 us, StdErr = 0.002 us (0.12%), N = 15, StdDev = 0.007 usMin = 1.390 us, Q1 = 1.397 us, Median = 1.401 us, Q3 = 1.404 us, Max = 1.412 usIQR = 0.007 us, LowerFence = 1.386 us, UpperFence = 1.415 usConfidenceInterval = [1.394 us; 1.408 us] (CI 99.9%), Margin = 0.007 us (0.51% of Mean)Skewness = -0.05, Kurtosis = 1.92, MValue = 2-------------------- Histogram --------------------[1.386 us ; 1.415 us) | @@@@@@@@@@@@@@@---------------------------------------------------SearchValuesBenchmark2.WithIndexofAnyAndCharArray: DefaultJob [StringCount=100]Runtime = .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2; GC = Concurrent WorkstationMean = 1.871 us, StdErr = 0.009 us (0.47%), N = 16, StdDev = 0.035 usMin = 1.823 us, Q1 = 1.845 us, Median = 1.862 us, Q3 = 1.895 us, Max = 1.936 usIQR = 0.050 us, LowerFence = 1.771 us, UpperFence = 1.969 usConfidenceInterval = [1.835 us; 1.907 us] (CI 99.9%), Margin = 0.036 us (1.92% of Mean)Skewness = 0.55, Kurtosis = 1.89, MValue = 2-------------------- Histogram --------------------[1.804 us ; 1.871 us) | @@@@@@@@@@[1.871 us ; 1.955 us) | @@@@@@---------------------------------------------------SearchValuesBenchmark2.WithSearchValuesContains: DefaultJob [StringCount=1000]Runtime = .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2; GC = Concurrent WorkstationMean = 16.237 us, StdErr = 0.022 us (0.13%), N = 15, StdDev = 0.083 usMin = 16.087 us, Q1 = 16.187 us, Median = 16.252 us, Q3 = 16.306 us, Max = 16.352 usIQR = 0.119 us, LowerFence = 16.009 us, UpperFence = 16.484 usConfidenceInterval = [16.148 us; 16.326 us] (CI 99.9%), Margin = 0.089 us (0.55% of Mean)Skewness = -0.38, Kurtosis = 1.67, MValue = 2-------------------- Histogram --------------------[16.042 us ; 16.397 us) | @@@@@@@@@@@@@@@---------------------------------------------------SearchValuesBenchmark2.WithIndexofAnyAndCharArray: DefaultJob [StringCount=1000]Runtime = .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2; GC = Concurrent WorkstationMean = 24.508 us, StdErr = 0.074 us (0.30%), N = 15, StdDev = 0.285 usMin = 24.142 us, Q1 = 24.260 us, Median = 24.549 us, Q3 = 24.693 us, Max = 25.046 usIQR = 0.434 us, LowerFence = 23.609 us, UpperFence = 25.344 usConfidenceInterval = [24.204 us; 24.813 us] (CI 99.9%), Margin = 0.304 us (1.24% of Mean)Skewness = 0.28, Kurtosis = 1.77, MValue = 2-------------------- Histogram --------------------[24.036 us ; 25.197 us) | @@@@@@@@@@@@@@@---------------------------------------------------// * Summary *BenchmarkDotNet v0.14.0, Windows 11 (10.0.22631.4602/23H2/2023Update/SunValley3)AMD Ryzen Threadripper 3960X, 1 CPU, 48 logical and 24 physical cores.NET SDK 9.0.102  [Host]     : .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2  DefaultJob : .NET 9.0.1 (9.0.124.61010), X64 RyuJIT AVX2| Method                     | StringCount | Mean        | Error     | StdDev    | Ratio | RatioSD | Rank | Gen0   | Allocated | Alloc Ratio ||--------------------------- |------------ |------------:|----------:|----------:|------:|--------:|-----:|-------:|----------:|------------:|| WithSearchValuesContains   | 10          |    116.0 ns |   0.40 ns |   0.37 ns |  0.70 |    0.01 |    1 |      - |         - |        0.00 || WithIndexofAnyAndCharArray | 10          |    165.2 ns |   1.96 ns |   1.74 ns |  1.00 |    0.01 |    2 | 0.0381 |     320 B |        1.00 ||                            |             |             |           |           |       |         |      |        |           |             || WithSearchValuesContains   | 100         |  1,400.7 ns |   7.11 ns |   6.65 ns |  0.75 |    0.01 |    1 |      - |         - |        0.00 || WithIndexofAnyAndCharArray | 100         |  1,871.4 ns |  36.00 ns |  35.36 ns |  1.00 |    0.03 |    2 | 0.3815 |    3200 B |        1.00 ||                            |             |             |           |           |       |         |      |        |           |             || WithSearchValuesContains   | 1000        | 16,236.8 ns |  89.07 ns |  83.32 ns |  0.66 |    0.01 |    1 |      - |         - |        0.00 || WithIndexofAnyAndCharArray | 1000        | 24,508.3 ns | 304.39 ns | 284.73 ns |  1.00 |    0.02 |    2 | 3.8147 |   32000 B |        1.00 |

PR Context

PR Checklist

@ArmaanMcleodArmaanMcleod changed the titleRemove char[] array in CompletionRequiresQuotes and use cached SearchValues<char> with ContainsCharToCheck methodRemovechar[] array inCompletionRequiresQuotes and use cachedSearchValues<char> withContainsCharToCheck methodJan 31, 2025
@iSazonov
Copy link
Collaborator

/azp run

@azure-pipelinesAzure Pipelines
Copy link

Azure Pipelines successfully started running 4 pipeline(s).

@iSazonov

This comment was marked as outdated.

@azure-pipelinesAzure Pipelines

This comment was marked as outdated.

@iSazonoviSazonov added the CL-CodeCleanupIndicates that a PR should be marked as a Code Cleanup change in the Change Log labelFeb 1, 2025
@iSazonoviSazonov reopened thisFeb 1, 2025
@iSazonoviSazonov reopened thisFeb 1, 2025
@iSazonov
Copy link
Collaborator

/azp run

@azure-pipelinesAzure Pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@iSazonoviSazonov self-assigned thisFeb 1, 2025
@iSazonoviSazonov changed the titleRemovechar[] array inCompletionRequiresQuotes and use cachedSearchValues<char> withContainsCharToCheck methodReplace char[] array in CompletionRequiresQuotes with cached SearchValues<char>Feb 1, 2025
@iSazonoviSazonov merged commited982b4 intoPowerShell:masterFeb 1, 2025
60 of 62 checks passed
@microsoft-github-policy-serviceMicrosoft GitHub Policy Service
Copy link
Contributor

microsoft-github-policy-servicebot commentedFeb 1, 2025
edited by unfurl-linksbot
Loading

📣 Hey@ArmaanMcleod, how did we do? We would love to hear your feedback with the link below! 🗣️

🔗https://aka.ms/PSRepoFeedback

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@iSazonoviSazonoviSazonov approved these changes

Assignees

@iSazonoviSazonov

Labels
CL-CodeCleanupIndicates that a PR should be marked as a Code Cleanup change in the Change Log
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

2 participants
@ArmaanMcleod@iSazonov

[8]ページ先頭

©2009-2025 Movatter.jp