feat: create an overload for Any( SyntaxTriviaList to prevent allocations#1485
Merged
belav merged 2 commits intobelav:mainfrom Feb 21, 2025
Merged
feat: create an overload for Any( SyntaxTriviaList to prevent allocations#1485belav merged 2 commits intobelav:mainfrom
Any( SyntaxTriviaList to prevent allocations#1485belav merged 2 commits intobelav:mainfrom
Conversation
cc9007f to
18e8b22
Compare
18e8b22 to
be957bc
Compare
belav
pushed a commit
that referenced
this pull request
Feb 21, 2025
…#1486) Similar to #1485, use a manual `foreach` where loop to prevent boxing of `SyntaxTriviaList`, `SyntaxTriviaList.EnumeratorImpl` and `WhereIterator`. ### Before  ### After 
belav
approved these changes
Feb 21, 2025
TimothyMakkison
added a commit
to TimothyMakkison/csharpier
that referenced
this pull request
Feb 24, 2025
…belav#1486) Similar to belav#1485, use a manual `foreach` where loop to prevent boxing of `SyntaxTriviaList`, `SyntaxTriviaList.EnumeratorImpl` and `WhereIterator`. ### Before  ### After 
TimothyMakkison
added a commit
to TimothyMakkison/csharpier
that referenced
this pull request
Feb 24, 2025
…ations (belav#1485) Creates an extension method that overloads `Any(this SyntaxTriviaList)` this uses the struct `SyntaxTriviaList.Enumerator` to iterate, instead of allocating the class `SyntaxTriviaList.EnumeratorImpl : IEnumerator<SyntaxTrivia>` and boxing `SyntaxTrviaList`. Saves around 11% of memory aka 11MB on the benchmark. ## Benchmarks ### Before | Method | Mean | Error | StdDev | Median | Gen0 | Gen1 | Gen2 | Allocated | |---------------------------------------- |--------------:|-------------:|-------------:|--------------:|-----------:|----------:|----------:|------------:| | Default_CodeFormatter | 187,771.22 us | 3,718.757 us | 6,705.686 us | 187,214.50 us | 11000.0000 | 4000.0000 | 1000.0000 | 98124.57 KB | | Default_SyntaxNodeComparer | 1,920.62 us | 77.064 us | 227.225 us | 1,840.56 us | 66.4063 | 15.6250 | - | 643.28 KB | | IsCodeBasicallyEqual_SyntaxNodeComparer | 97.11 us | 3.195 us | 9.421 us | 96.33 us | 10.7422 | 1.3428 | - | 99.02 KB | ### After | Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | |---------------------------------------- |--------------:|-------------:|-------------:|-----------:|----------:|----------:|------------:| | Default_CodeFormatter | 180,664.34 us | 3,555.331 us | 6,037.222 us | 10000.0000 | 4000.0000 | 1000.0000 | 87296.88 KB | | Default_SyntaxNodeComparer | 2,315.61 us | 105.286 us | 310.439 us | 66.4063 | 15.6250 | - | 643.28 KB | | IsCodeBasicallyEqual_SyntaxNodeComparer | 84.32 us | 1.638 us | 2.297 us | 10.7422 | 1.3428 | - | 99.02 KB | Co-authored-by: Bela VanderVoort <[email protected]>
belav
added a commit
that referenced
this pull request
Dec 25, 2025
…#1703) Semi reverts #1572 which overwrote #1485, I assume this was accidental. I noticed that you prefer explicit `Enumerable.Any` usage, should I convert this PR to use `ListExtensions.Any`? ## Benchmarks Saves around 15% of memory usage ### Before | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |------------------------------ |---------:|--------:|--------:|----------:|----------:|----------:| | Default_CodeFormatter_Tests | 128.0 ms | 2.44 ms | 3.43 ms | 3000.0000 | 1000.0000 | 34.57 MB | | Default_CodeFormatter_Complex | 260.3 ms | 5.11 ms | 7.17 ms | 5000.0000 | 2000.0000 | 53.05 MB | ### After | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |------------------------------ |---------:|--------:|---------:|----------:|----------:|----------:| | Default_CodeFormatter_Tests | 126.0 ms | 2.27 ms | 5.45 ms | 2000.0000 | 1000.0000 | 28.02 MB | | Default_CodeFormatter_Complex | 245.2 ms | 4.63 ms | 10.44 ms | 4000.0000 | 2000.0000 | 43.88 MB | Co-authored-by: Bela VanderVoort <[email protected]>
belav
added a commit
that referenced
this pull request
Dec 31, 2025
…#1703) Semi reverts #1572 which overwrote #1485, I assume this was accidental. I noticed that you prefer explicit `Enumerable.Any` usage, should I convert this PR to use `ListExtensions.Any`? ## Benchmarks Saves around 15% of memory usage ### Before | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |------------------------------ |---------:|--------:|--------:|----------:|----------:|----------:| | Default_CodeFormatter_Tests | 128.0 ms | 2.44 ms | 3.43 ms | 3000.0000 | 1000.0000 | 34.57 MB | | Default_CodeFormatter_Complex | 260.3 ms | 5.11 ms | 7.17 ms | 5000.0000 | 2000.0000 | 53.05 MB | ### After | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |------------------------------ |---------:|--------:|---------:|----------:|----------:|----------:| | Default_CodeFormatter_Tests | 126.0 ms | 2.27 ms | 5.45 ms | 2000.0000 | 1000.0000 | 28.02 MB | | Default_CodeFormatter_Complex | 245.2 ms | 4.63 ms | 10.44 ms | 4000.0000 | 2000.0000 | 43.88 MB | Co-authored-by: Bela VanderVoort <[email protected]>
belav
added a commit
that referenced
this pull request
Feb 20, 2026
…#1703) Semi reverts #1572 which overwrote #1485, I assume this was accidental. I noticed that you prefer explicit `Enumerable.Any` usage, should I convert this PR to use `ListExtensions.Any`? ## Benchmarks Saves around 15% of memory usage ### Before | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |------------------------------ |---------:|--------:|--------:|----------:|----------:|----------:| | Default_CodeFormatter_Tests | 128.0 ms | 2.44 ms | 3.43 ms | 3000.0000 | 1000.0000 | 34.57 MB | | Default_CodeFormatter_Complex | 260.3 ms | 5.11 ms | 7.17 ms | 5000.0000 | 2000.0000 | 53.05 MB | ### After | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |------------------------------ |---------:|--------:|---------:|----------:|----------:|----------:| | Default_CodeFormatter_Tests | 126.0 ms | 2.27 ms | 5.45 ms | 2000.0000 | 1000.0000 | 28.02 MB | | Default_CodeFormatter_Complex | 245.2 ms | 4.63 ms | 10.44 ms | 4000.0000 | 2000.0000 | 43.88 MB | Co-authored-by: Bela VanderVoort <[email protected]>
belav
added a commit
that referenced
this pull request
Mar 12, 2026
…#1703) Semi reverts #1572 which overwrote #1485, I assume this was accidental. I noticed that you prefer explicit `Enumerable.Any` usage, should I convert this PR to use `ListExtensions.Any`? ## Benchmarks Saves around 15% of memory usage ### Before | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |------------------------------ |---------:|--------:|--------:|----------:|----------:|----------:| | Default_CodeFormatter_Tests | 128.0 ms | 2.44 ms | 3.43 ms | 3000.0000 | 1000.0000 | 34.57 MB | | Default_CodeFormatter_Complex | 260.3 ms | 5.11 ms | 7.17 ms | 5000.0000 | 2000.0000 | 53.05 MB | ### After | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |------------------------------ |---------:|--------:|---------:|----------:|----------:|----------:| | Default_CodeFormatter_Tests | 126.0 ms | 2.27 ms | 5.45 ms | 2000.0000 | 1000.0000 | 28.02 MB | | Default_CodeFormatter_Complex | 245.2 ms | 4.63 ms | 10.44 ms | 4000.0000 | 2000.0000 | 43.88 MB | Co-authored-by: Bela VanderVoort <[email protected]>
belav
added a commit
that referenced
this pull request
Apr 4, 2026
…#1703) Semi reverts #1572 which overwrote #1485, I assume this was accidental. I noticed that you prefer explicit `Enumerable.Any` usage, should I convert this PR to use `ListExtensions.Any`? ## Benchmarks Saves around 15% of memory usage ### Before | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |------------------------------ |---------:|--------:|--------:|----------:|----------:|----------:| | Default_CodeFormatter_Tests | 128.0 ms | 2.44 ms | 3.43 ms | 3000.0000 | 1000.0000 | 34.57 MB | | Default_CodeFormatter_Complex | 260.3 ms | 5.11 ms | 7.17 ms | 5000.0000 | 2000.0000 | 53.05 MB | ### After | Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |------------------------------ |---------:|--------:|---------:|----------:|----------:|----------:| | Default_CodeFormatter_Tests | 126.0 ms | 2.27 ms | 5.45 ms | 2000.0000 | 1000.0000 | 28.02 MB | | Default_CodeFormatter_Complex | 245.2 ms | 4.63 ms | 10.44 ms | 4000.0000 | 2000.0000 | 43.88 MB | Co-authored-by: Bela VanderVoort <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Creates an extension method that overloads
Any(this SyntaxTriviaList)this uses the structSyntaxTriviaList.Enumeratorto iterate, instead of allocating the classSyntaxTriviaList.EnumeratorImpl : IEnumerator<SyntaxTrivia>and boxingSyntaxTrviaList.Saves around 11% of memory aka 11MB on the benchmark.
Benchmarks
Before
After