├── .dockerignore
├── .github
├── dependabot.yml
└── workflows
│ ├── dependabotautomerge.yml
│ └── dotnet-ci.yml
├── .gitignore
├── Benchmarks.sln
├── Benchmarks.sln.DotSettings
├── LICENSE
├── README.md
├── assets
├── benchmark.enum
│ ├── enum-name.png
│ └── enum-value.png
├── benchmarks.collectionsize
│ ├── any-10k-elements.png
│ ├── any-empty.png
│ ├── count-10k-elements.png
│ └── count-empty.png
├── benchmarks.groupbyvsdistinct
│ ├── group-10.png
│ └── group-10k.png
├── benchmarks.serializers.binary
│ ├── deserialization-1.png
│ ├── deserialization-1k.png
│ ├── serialization-1.png
│ └── serialization-1k.png
├── benchmarks.serializers.json
│ ├── deserialization-byte-1.png
│ ├── deserialization-byte-1k.png
│ ├── deserialization-string-1.png
│ ├── deserialization-string-1k.png
│ ├── serialization-byte-1.png
│ ├── serialization-byte-1k.png
│ ├── serialization-string-1.png
│ └── serialization-string-1k.png
└── icon.png
├── coverlet.runsettings
├── docfx.json
├── docs
├── getting-started.md
├── introduction.md
└── toc.yml
├── global.json
├── index.md
├── src
├── main
│ ├── Benchmarks.CollectionSize
│ │ ├── Benchmarks.CollectionSize.csproj
│ │ ├── Benchmarks
│ │ │ └── AnyLengthBenchmarks.cs
│ │ ├── Dockerfile
│ │ ├── Group.cs
│ │ ├── Models
│ │ │ └── TestCollections.cs
│ │ ├── Program.cs
│ │ ├── Readme.md
│ │ └── Services
│ │ │ ├── AnyLengthService.Any.cs
│ │ │ ├── AnyLengthService.Count.cs
│ │ │ ├── AnyLengthService.CountPattern.cs
│ │ │ └── AnyLengthService.cs
│ ├── Benchmarks.Common
│ │ ├── Benchmarks.Common.csproj
│ │ └── FakerExtensions.cs
│ ├── Benchmarks.DynamicPredicateParser
│ │ ├── Benchmarks.DynamicPredicateParser.csproj
│ │ ├── Dockerfile
│ │ ├── ParserBenchmarks.cs
│ │ ├── Program.cs
│ │ ├── TestModel.cs
│ │ └── readme.md
│ ├── Benchmarks.Enum
│ │ ├── Benchmarks.Enum.csproj
│ │ ├── Benchmarks
│ │ │ ├── EnumBenchmarksBase.cs
│ │ │ ├── EnumNameBenchmarks.cs
│ │ │ └── EnumValueBenchmarks.cs
│ │ ├── Dockerfile
│ │ ├── Extensions
│ │ │ └── EnumExtensions.cs
│ │ ├── Group.cs
│ │ ├── Program.cs
│ │ ├── Readme.md
│ │ ├── Services
│ │ │ ├── EnumNameService.cs
│ │ │ └── EnumValueService.cs
│ │ └── TestEnum.cs
│ ├── Benchmarks.Flattening
│ │ ├── Benchmarks.Flattening.csproj
│ │ ├── FlatBenchmarks.cs
│ │ ├── InternalModel.cs
│ │ ├── Program.cs
│ │ ├── README.MD
│ │ └── UnflatModel.cs
│ ├── Benchmarks.GroupByVsDistinct
│ │ ├── Benchmarks.GroupByVsDistinct.csproj
│ │ ├── DistinctGroupByBenchmarks.cs
│ │ ├── Dockerfile
│ │ ├── Models
│ │ │ ├── InnerModel.cs
│ │ │ └── SimpleModel.cs
│ │ ├── Program.cs
│ │ ├── Readme.md
│ │ └── Services
│ │ │ └── LinqService.cs
│ ├── Benchmarks.Iterators
│ │ ├── Benchmarks.Iterators.csproj
│ │ ├── Benchmarks
│ │ │ ├── BenchmarksBase.cs
│ │ │ ├── IteratorBenchmarks.Array.cs
│ │ │ ├── IteratorBenchmarks.ICollection.cs
│ │ │ ├── IteratorBenchmarks.List.cs
│ │ │ ├── IteratorBenchmarks.Serializing.cs
│ │ │ └── IteratorBenchmarks.cs
│ │ ├── Dockerfile
│ │ ├── Group.cs
│ │ ├── Models
│ │ │ └── SimpleModel.cs
│ │ ├── Program.cs
│ │ ├── Readme.md
│ │ └── Services
│ │ │ ├── IterationService.Array.cs
│ │ │ ├── IterationService.Collection.cs
│ │ │ ├── IterationService.List.cs
│ │ │ └── IterationService.cs
│ ├── Benchmarks.QueryBuilder
│ │ ├── Benchmarks.QueryBuilder.csproj
│ │ ├── Benchmarks
│ │ │ ├── QueryBuilderBenchmarks.cs
│ │ │ └── UriCombineBenchmarks.cs
│ │ ├── Dockerfile
│ │ ├── Group.cs
│ │ ├── Program.cs
│ │ ├── Services
│ │ │ ├── Query
│ │ │ │ ├── QueryClass.cs
│ │ │ │ ├── QueryCustomBuilder.cs
│ │ │ │ ├── QueryService.cs
│ │ │ │ ├── QueryValueStringBuilder.cs
│ │ │ │ └── ValueStringBuilder.cs
│ │ │ └── Uri
│ │ │ │ ├── StringUriCombineService.cs
│ │ │ │ └── UriCombineService.cs
│ │ └── readme.md
│ ├── Benchmarks.Serializers.Binary
│ │ ├── Benchmarks.Serializers.Binary.csproj
│ │ ├── Benchmarks
│ │ │ ├── DeserializationBenchmark.cs
│ │ │ └── SerializationBenchmark.cs
│ │ ├── Dockerfile
│ │ ├── MsgPackLightConverters
│ │ │ ├── SimpleModelConverter.cs
│ │ │ └── SimpleModelsConverter.cs
│ │ ├── Program.cs
│ │ ├── Readme.md
│ │ ├── SerializationBenchmark.FlatBuffer.cs
│ │ ├── SerializationBenchmark.MemoryPack.cs
│ │ ├── SerializationBenchmark.MessagePack.cs
│ │ ├── SerializationBenchmark.Protobuf.cs
│ │ ├── SerializationBenchmark.ZeroFormatter.cs
│ │ ├── Serializers.MsgPackLight.cs
│ │ └── Serializers.cs
│ ├── Benchmarks.Serializers.Json
│ │ ├── Benchmarks.Serializers.Json.csproj
│ │ ├── Benchmarks
│ │ │ ├── Deserialization
│ │ │ │ └── Simple
│ │ │ │ │ ├── AsyncStreamDeserializationSimpleBenchmarks.cs
│ │ │ │ │ ├── ByteDeserializationSimpleBenchmarks.cs
│ │ │ │ │ ├── StreamDeserializationSimpleBenchmarks.cs
│ │ │ │ │ └── StringDeserializationSimpleBenchmarks.cs
│ │ │ ├── DeserializationBenchmark.Jil.cs
│ │ │ ├── DeserializationBenchmark.JsonSrcGen.cs
│ │ │ ├── DeserializationBenchmark.NetJson.cs
│ │ │ ├── DeserializationBenchmark.Newtonsoft.cs
│ │ │ ├── DeserializationBenchmark.ServiceStack.cs
│ │ │ ├── DeserializationBenchmark.SpanJson.cs
│ │ │ ├── DeserializationBenchmark.SystemTextJson.cs
│ │ │ ├── DeserializationBenchmark.SystemTextJsonSrcGen.cs
│ │ │ ├── DeserializationBenchmark.Utf8Json.cs
│ │ │ ├── DeserializationBenchmark.cs
│ │ │ ├── JsonComplexBenchmark.cs
│ │ │ ├── SerializationBenchmark.Jil.cs
│ │ │ ├── SerializationBenchmark.JsonSrcGen.cs
│ │ │ ├── SerializationBenchmark.NetJson.cs
│ │ │ ├── SerializationBenchmark.Newtonsoft.cs
│ │ │ ├── SerializationBenchmark.ServiceStack.cs
│ │ │ ├── SerializationBenchmark.SpanJson.cs
│ │ │ ├── SerializationBenchmark.SystemTextJson.cs
│ │ │ ├── SerializationBenchmark.SystemTextJsonSrcGen.cs
│ │ │ ├── SerializationBenchmark.Utf8Json.cs
│ │ │ └── SerializationBenchmark.cs
│ │ ├── Dockerfile
│ │ ├── Extensions
│ │ │ └── JsonServiceExtensions.cs
│ │ ├── Models
│ │ │ ├── ComplexSrcGenModel.cs
│ │ │ └── SimpleSrcGenModel.cs
│ │ ├── Program.cs
│ │ ├── Readme.md
│ │ ├── Serializers.Jil.cs
│ │ ├── Serializers.JsonSrcGen.cs
│ │ ├── Serializers.NetJson.cs
│ │ ├── Serializers.Newtonsoft.cs
│ │ ├── Serializers.ServiceStack.cs
│ │ ├── Serializers.SpanJson.cs
│ │ ├── Serializers.SystemTextJson.cs
│ │ ├── Serializers.SystemTextJsonSrcGen.cs
│ │ ├── Serializers.Utf8Json.cs
│ │ └── Serializers.cs
│ ├── Benchmarks.Serializers.OutputFormatters
│ │ ├── Benchmarks.Serializers.OutputFormatters.csproj
│ │ ├── Benchmarks.Serializers.OutputFormatters.http
│ │ ├── Controllers
│ │ │ └── JsonController.cs
│ │ ├── Dockerfile
│ │ ├── Extensions
│ │ │ └── SimpleModelGenerator.cs
│ │ ├── Formatters
│ │ │ ├── Jil
│ │ │ │ ├── JilInputFormatter.cs
│ │ │ │ ├── JilOutputFormatter.cs
│ │ │ │ └── MvcOptionsExtensions.cs
│ │ │ ├── MemoryPack
│ │ │ │ └── MvcOptionsExtensions.cs
│ │ │ ├── MessagePack
│ │ │ │ └── MvcOptionsExtensions.cs
│ │ │ ├── Newtonsoft
│ │ │ │ └── MvcOptionsExtensions.cs
│ │ │ ├── Protobuf
│ │ │ │ └── MvcOptionsExtensions.cs
│ │ │ ├── SpanJson
│ │ │ │ ├── MvcOptionsExtensions.cs
│ │ │ │ ├── SpanJsonFormatter.cs
│ │ │ │ ├── SpanJsonInputFormatter.cs
│ │ │ │ └── SpanJsonOutputFormatter.cs
│ │ │ ├── SystemTextJson
│ │ │ │ └── MvcOptionsExtensions.cs
│ │ │ └── Utf8Json
│ │ │ │ └── MvcOptionsExtensions.cs
│ │ ├── Program.cs
│ │ ├── appsettings.json
│ │ └── locustfile.py
│ ├── Benchmarks.Serializers
│ │ ├── Benchmark
│ │ │ └── Serializers
│ │ │ │ └── Models
│ │ │ │ ├── SimpleFlatBufferModel.cs
│ │ │ │ └── SimpleFlatBufferModels.cs
│ │ ├── Benchmarks.Serializers.csproj
│ │ ├── Fields.cs
│ │ ├── Group.cs
│ │ ├── Models
│ │ │ ├── ComplexModel.cs
│ │ │ └── SimpleModel.cs
│ │ ├── ModelsJsonContext.cs
│ │ └── SimpleFlatBufferModel.fbs
│ ├── Benchmarks.SortArrayByArray
│ │ ├── Benchmarks.SortArrayByArray.csproj
│ │ ├── Extensions
│ │ │ ├── EnumerableExtensions.cs
│ │ │ └── SortExtensions.cs
│ │ ├── Program.cs
│ │ ├── SortBenchmarks.cs
│ │ ├── TestModel.cs
│ │ └── readme.md
│ ├── Benchmarks.Stopwatch
│ │ ├── Benchmarks.Stopwatch.csproj
│ │ ├── Program.cs
│ │ ├── README.MD
│ │ └── TimeBenchmarks.cs
│ └── Benchmarks.String
│ │ ├── Benchmarks.String.csproj
│ │ ├── Benchmarks
│ │ ├── Abstractions
│ │ │ ├── BenchmarkBase.cs
│ │ │ └── BenchmarkCollectionBase.cs
│ │ ├── ContainsCharBenchmarks.cs
│ │ ├── DashStringBenchmarks.cs
│ │ ├── GenerationBenchmarks.cs
│ │ ├── InterpolationBenchmarks.cs
│ │ ├── LinkStringBenchmarks.cs
│ │ ├── SingleDashStringBenchmarks.cs
│ │ └── SingleLinkStringBenchmarks.cs
│ │ ├── Constants.cs
│ │ ├── Dockerfile
│ │ ├── Group.cs
│ │ ├── Models
│ │ ├── InterpolationModel.cs
│ │ └── StringsTestModel.cs
│ │ ├── Program.cs
│ │ ├── Readme.md
│ │ └── Services
│ │ ├── ArrayPoolStringService.cs
│ │ ├── GenerationService.cs
│ │ ├── InterpolationService.cs
│ │ ├── RegexStringService.cs
│ │ └── SpanOwnerStringService.cs
└── test
│ └── Benchmarks.Tests.Unit
│ ├── Benchmark.Enum
│ ├── EnumNameTests.cs
│ └── EnumValueTests.cs
│ ├── Benchmark.GroupByVsDistinct
│ └── LinqTests.cs
│ ├── Benchmark.Iterators
│ ├── IteratorTests.cs
│ └── TestModel.cs
│ ├── Benchmark.QueryBuilder
│ ├── QueryTests.cs
│ ├── StringUriTests.cs
│ └── UriUrlTests.cs
│ ├── Benchmark.Serializers
│ ├── Json
│ │ ├── JilTests.cs
│ │ ├── NetJsonTests.cs
│ │ ├── NewtonsoftJsonTests.cs
│ │ ├── ServiceStackTests.cs
│ │ ├── SpanJsonTests.cs
│ │ ├── SystemTextJsonTests.cs
│ │ ├── TestsBase.cs
│ │ └── Utf8JsonTests.cs
│ └── Models
│ │ └── TestModel.cs
│ ├── Benchmark.String
│ ├── ArrayPoolStringTests.cs
│ ├── GenerationTests.cs
│ ├── InterpolationTests.cs
│ ├── RegexStringTests.cs
│ └── SpanOwnerStringTests.cs
│ ├── Benchmarks.Tests.Unit.csproj
│ └── GlobalUsings.cs
└── toc.yml
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/.dockerignore
2 | **/.env
3 | **/.git
4 | **/.gitignore
5 | **/.project
6 | **/.settings
7 | **/.toolstarget
8 | **/.vs
9 | **/.vscode
10 | **/.idea
11 | **/*.*proj.user
12 | **/*.dbmdl
13 | **/*.jfm
14 | **/azds.yaml
15 | **/bin
16 | **/charts
17 | **/docker-compose*
18 | **/Dockerfile*
19 | **/node_modules
20 | **/npm-debug.log
21 | **/obj
22 | **/secrets.dev.yaml
23 | **/values.dev.yaml
24 | LICENSE
25 | README.md
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # Please see the documentation for all configuration options:
2 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
3 |
4 | version: 2
5 | updates:
6 | # NuGet (/*.csproj)
7 | - package-ecosystem: nuget
8 | directory: '/'
9 | schedule:
10 | interval: weekly
11 | time: '08:00'
12 | timezone: Europe/Kyiv
13 | labels:
14 | - 'dependabot:robot:'
15 | commit-message:
16 | prefix: fix
17 | prefix-development: chore
18 | include: scope
19 |
20 | # GitHub Actions (/.github/workflows/*.yml)
21 | - package-ecosystem: github-actions
22 | directory: '/'
23 | schedule:
24 | interval: weekly
25 | time: '08:00'
26 | timezone: Europe/Kyiv
27 | labels:
28 | - 'dependabot:robot:'
29 | commit-message:
30 | prefix: fix
31 | prefix-development: chore
32 | include: scope
33 |
--------------------------------------------------------------------------------
/.github/workflows/dependabotautomerge.yml:
--------------------------------------------------------------------------------
1 | name: "Dependabot Automerge - Action"
2 |
3 | on:
4 | pull_request:
5 |
6 | permissions:
7 | contents: write
8 | pull-requests: write
9 |
10 | jobs:
11 | worker:
12 | runs-on: ubuntu-latest
13 |
14 | if: github.actor == 'dependabot[bot]'
15 | steps:
16 | - name: automerge
17 | uses: actions/github-script@0.2.0
18 | with:
19 | script: |
20 | github.pullRequests.createReview({
21 | owner: context.payload.repository.owner.login,
22 | repo: context.payload.repository.name,
23 | pull_number: context.payload.pull_request.number,
24 | event: 'APPROVE'
25 | })
26 | github.pullRequests.merge({
27 | owner: context.payload.repository.owner.login,
28 | repo: context.payload.repository.name,
29 | pull_number: context.payload.pull_request.number
30 | })
31 | github-token: ${{secrets.GITHUB_TOKEN}}
--------------------------------------------------------------------------------
/.github/workflows/dotnet-ci.yml:
--------------------------------------------------------------------------------
1 | name: .NET
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 | - name: Setup .NET
15 | uses: actions/setup-dotnet@v4
16 | with:
17 | dotnet-version: '9.x.x'
18 | - name: Restore dependencies
19 | run: dotnet restore
20 | - name: Build
21 | run: dotnet build --no-restore
22 | - name: Test
23 | run: dotnet test --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutput=TestResults/ /p:CoverletOutputFormat=opencover
24 | - name: Publish coverage report
25 | uses: codecov/codecov-action@v4
26 | with:
27 | token: ${{ secrets.CODECOV_TOKEN }}
28 |
--------------------------------------------------------------------------------
/Benchmarks.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021-2024 Ihor Volokhovych
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/assets/benchmark.enum/enum-name.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmark.enum/enum-name.png
--------------------------------------------------------------------------------
/assets/benchmark.enum/enum-value.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmark.enum/enum-value.png
--------------------------------------------------------------------------------
/assets/benchmarks.collectionsize/any-10k-elements.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.collectionsize/any-10k-elements.png
--------------------------------------------------------------------------------
/assets/benchmarks.collectionsize/any-empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.collectionsize/any-empty.png
--------------------------------------------------------------------------------
/assets/benchmarks.collectionsize/count-10k-elements.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.collectionsize/count-10k-elements.png
--------------------------------------------------------------------------------
/assets/benchmarks.collectionsize/count-empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.collectionsize/count-empty.png
--------------------------------------------------------------------------------
/assets/benchmarks.groupbyvsdistinct/group-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.groupbyvsdistinct/group-10.png
--------------------------------------------------------------------------------
/assets/benchmarks.groupbyvsdistinct/group-10k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.groupbyvsdistinct/group-10k.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.binary/deserialization-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.binary/deserialization-1.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.binary/deserialization-1k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.binary/deserialization-1k.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.binary/serialization-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.binary/serialization-1.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.binary/serialization-1k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.binary/serialization-1k.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.json/deserialization-byte-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.json/deserialization-byte-1.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.json/deserialization-byte-1k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.json/deserialization-byte-1k.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.json/deserialization-string-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.json/deserialization-string-1.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.json/deserialization-string-1k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.json/deserialization-string-1k.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.json/serialization-byte-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.json/serialization-byte-1.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.json/serialization-byte-1k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.json/serialization-byte-1k.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.json/serialization-string-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.json/serialization-string-1.png
--------------------------------------------------------------------------------
/assets/benchmarks.serializers.json/serialization-string-1k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/benchmarks.serializers.json/serialization-string-1k.png
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antomys/CuriousBenchmarks/784b131aee62a3653e58d0679af671b3f9c6ae0c/assets/icon.png
--------------------------------------------------------------------------------
/coverlet.runsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | opencover
8 | [*.Test]*,[*]*.Program
9 | Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute
10 | false
11 | true
12 | true
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docfx.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": [
3 | {
4 | "src": [
5 | {
6 | "src": "../src/main",
7 | "files": [
8 | "**/*.csproj"
9 | ]
10 | }
11 | ],
12 | "dest": "api"
13 | }
14 | ],
15 | "build": {
16 | "content": [
17 | {
18 | "files": [
19 | "**/*.{md,yml}"
20 | ],
21 | "exclude": [
22 | "_site/**"
23 | ]
24 | }
25 | ],
26 | "resource": [
27 | {
28 | "files": [
29 | "images/**"
30 | ]
31 | }
32 | ],
33 | "output": "_site",
34 | "template": [
35 | "default",
36 | "modern"
37 | ],
38 | "globalMetadata": {
39 | "_appName": "curious-benchmarks",
40 | "_appTitle": "curious-benchmarks",
41 | "_enableSearch": true,
42 | "pdf": true
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/docs/getting-started.md:
--------------------------------------------------------------------------------
1 | # Getting Started
--------------------------------------------------------------------------------
/docs/introduction.md:
--------------------------------------------------------------------------------
1 | # Introduction
--------------------------------------------------------------------------------
/docs/toc.yml:
--------------------------------------------------------------------------------
1 | - name: Introduction
2 | href: introduction.md
3 | - name: Getting Started
4 | href: getting-started.md
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "8.0",
4 | "rollForward": "latestFeature",
5 | "allowPrerelease": false
6 | }
7 | }
--------------------------------------------------------------------------------
/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | _layout: landing
3 | ---
4 |
5 | # This is the **HOMEPAGE**.
6 |
7 | Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files.
8 |
9 | ## Quick Start Notes:
10 |
11 | 1. Add images to the *images* folder if the file is referencing an image.
--------------------------------------------------------------------------------
/src/main/Benchmarks.CollectionSize/Benchmarks.CollectionSize.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8
6 | enable
7 | enable
8 | Linux
9 |
10 |
11 |
12 |
13 | .dockerignore
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | AnyLengthService.cs
24 |
25 |
26 | AnyLengthService.cs
27 |
28 |
29 | AnyLengthService.cs
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.CollectionSize/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
2 | USER $APP_UID
3 | WORKDIR /app
4 |
5 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 | ARG BUILD_CONFIGURATION=Release
7 | WORKDIR /src
8 | COPY ["src/main/Benchmark.CollectionSize/Benchmark.CollectionSize.csproj", "src/main/Benchmark.CollectionSize/"]
9 | RUN dotnet restore "src/main/Benchmark.CollectionSize/Benchmark.CollectionSize.csproj"
10 | COPY . .
11 | WORKDIR "/src/src/main/Benchmark.CollectionSize"
12 | RUN dotnet build "Benchmark.CollectionSize.csproj" -c $BUILD_CONFIGURATION -o /app/build
13 |
14 | FROM build AS publish
15 | ARG BUILD_CONFIGURATION=Release
16 | RUN dotnet publish "Benchmark.CollectionSize.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
17 |
18 | FROM base AS final
19 | WORKDIR /app
20 | COPY --from=publish /app/publish .
21 | ENTRYPOINT ["dotnet", "Benchmark.CollectionSize.dll"]
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.CollectionSize/Group.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.CollectionSize;
2 |
3 | internal static class Group
4 | {
5 | internal const string CountExists = "Count Exists";
6 |
7 | internal const string CountPatternExists = "Count Pattern Exists";
8 |
9 | internal const string AnyExists = "Any Exists";
10 |
11 | internal const string CountEmpty = "Count Empty";
12 |
13 | internal const string CountPatternEmpty = "Count Pattern Empty";
14 |
15 | internal const string AnyEmpty = "Any Empty";
16 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.CollectionSize/Models/TestCollections.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.CollectionSize.Models;
2 |
3 | ///
4 | /// Model for storing different collections for benchmarks.
5 | ///
6 | public sealed class TestCollections
7 | {
8 | ///
9 | /// Collection of type.
10 | ///
11 | public string[] TestArray { get; init; }
12 |
13 | ///
14 | /// Collection of type.
15 | ///
16 | public List TestList { get; init; }
17 |
18 | ///
19 | /// Collection of type.
20 | ///
21 | public ICollection TestICollection { get; init; }
22 |
23 | ///
24 | /// Collection of type.
25 | ///
26 | public IEnumerable TestIEnumerable { get; init; }
27 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.CollectionSize/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 |
3 | BenchmarkRunner.Run(typeof(Program).Assembly);
--------------------------------------------------------------------------------
/src/main/Benchmarks.CollectionSize/Services/AnyLengthService.Any.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.CollectionSize.Services;
2 |
3 | internal static partial class AnyLengthService
4 | {
5 | public static bool AnyArray(this T[]? tArray)
6 | {
7 | return tArray is not null && tArray.Any();
8 | }
9 |
10 | public static bool AnyList(this List? tArray)
11 | {
12 | return tArray is not null && tArray.Any();
13 | }
14 |
15 | public static bool AnyCollection(this ICollection? tArray)
16 | {
17 | return tArray is not null && tArray.Any();
18 | }
19 |
20 | public static bool AnyEnumerable(this IEnumerable? tArray)
21 | {
22 | return tArray is not null && tArray.Any();
23 | }
24 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.CollectionSize/Services/AnyLengthService.Count.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.CollectionSize.Services;
2 |
3 | internal static partial class AnyLengthService
4 | {
5 | public static bool CountArray(this T[]? tArray)
6 | {
7 | return tArray is not null && tArray.Length > 0;
8 | }
9 |
10 | public static bool CountList(this List? tArray)
11 | {
12 | return tArray is not null && tArray.Count > 0;
13 | }
14 |
15 | public static bool CountCollection(this ICollection? tArray)
16 | {
17 | return tArray is not null && tArray.Count > 0;
18 | }
19 |
20 | public static bool CountEnumerable(this IEnumerable? tArray)
21 | {
22 | return tArray is not null && tArray.Count() > 0;
23 | }
24 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.CollectionSize/Services/AnyLengthService.CountPattern.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.CollectionSize.Services;
2 |
3 | internal static partial class AnyLengthService
4 | {
5 | public static bool CountArrayPattern(this T[]? tArray)
6 | {
7 | return tArray is {Length: > 0};
8 | }
9 |
10 | public static bool CountListPattern(this List? tArray)
11 | {
12 | return tArray is {Count: > 0};
13 | }
14 |
15 | public static bool CountCollectionPattern(this ICollection? tArray)
16 | {
17 | return tArray is {Count: > 0};
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.CollectionSize/Services/AnyLengthService.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.CollectionSize.Services;
2 |
3 | internal static partial class AnyLengthService;
--------------------------------------------------------------------------------
/src/main/Benchmarks.Common/Benchmarks.Common.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8
5 | enable
6 |
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.DynamicPredicateParser/Benchmarks.DynamicPredicateParser.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8
6 | enable
7 | enable
8 | Linux
9 |
10 |
11 |
12 |
13 | .dockerignore
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.DynamicPredicateParser/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
2 | USER $APP_UID
3 | WORKDIR /app
4 |
5 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 | ARG BUILD_CONFIGURATION=Release
7 | WORKDIR /src
8 | COPY ["src/main/Benchmarks.DynamicPredicateParser/Benchmarks.DynamicPredicateParser.csproj", "src/main/Benchmarks.DynamicPredicateParser/"]
9 | RUN dotnet restore "src/main/Benchmarks.DynamicPredicateParser/Benchmarks.DynamicPredicateParser.csproj"
10 | COPY . .
11 | WORKDIR "/src/src/main/Benchmarks.DynamicPredicateParser"
12 | RUN dotnet build "Benchmarks.DynamicPredicateParser.csproj" -c $BUILD_CONFIGURATION -o /app/build
13 |
14 | FROM build AS publish
15 | ARG BUILD_CONFIGURATION=Release
16 | RUN dotnet publish "Benchmarks.DynamicPredicateParser.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
17 |
18 | FROM base AS final
19 | WORKDIR /app
20 | COPY --from=publish /app/publish .
21 | ENTRYPOINT ["dotnet", "Benchmarks.DynamicPredicateParser.dll"]
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.DynamicPredicateParser/ParserBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using System.Linq.Dynamic.Core;
3 | using BenchmarkDotNet.Attributes;
4 | using BenchmarkDotNet.Configs;
5 | using BenchmarkDotNet.Engines;
6 | using BenchmarkDotNet.Order;
7 | using Bogus;
8 | using PredicateParser;
9 |
10 | namespace Benchmarks.DynamicPredicateParser;
11 |
12 | ///
13 | /// Distinct/GroupBy benchmarks.
14 | ///
15 | [MemoryDiagnoser, CategoriesColumn, AllStatisticsColumn, Orderer(SummaryOrderPolicy.FastestToSlowest),
16 | GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory), MarkdownExporterAttribute.GitHub, CsvMeasurementsExporter, RPlotExporter, ExcludeFromCodeCoverage]
17 | public class ParserBenchmarks
18 | {
19 | private const string Predicate = "Id==\"id\"&&Number==123";
20 |
21 | private readonly Consumer _consumer = new();
22 | private TestModel[] _testModels = [];
23 |
24 | ///
25 | /// Size of generation.
26 | /// **NOTE:** Intentionally left public for BenchmarkDotNet Params.
27 | ///
28 | [Params(100, 1000, 10000)]
29 | public int GenerationSize { get; set; }
30 |
31 | ///
32 | /// Setting private fields.
33 | ///
34 | [GlobalSetup]
35 | public void Setup()
36 | {
37 | var faker = new Faker()
38 | .RuleFor(x => x.Id, faker => faker.Random.String2(10))
39 | .RuleFor(x => x.Number, faker => faker.Random.Int())
40 | .Generate(GenerationSize - 1);
41 |
42 | faker.Add(new TestModel
43 | {
44 | Id = "id",
45 | Number = 123
46 | });
47 |
48 | _testModels = faker.ToArray();
49 | }
50 |
51 | ///
52 | /// Testing GroupBy and Take.
53 | ///
54 | [Benchmark(Baseline = true)]
55 | public TestModel? DynamicCore()
56 | {
57 | var predicate = DynamicExpressionParser
58 | .ParseLambda(
59 | ParsingConfig.Default,
60 | createParameterCtor: true,
61 | Predicate)
62 | .Compile();
63 |
64 | return _testModels.FirstOrDefault(predicate);
65 | }
66 |
67 | ///
68 | /// Testing GroupBy and Take.
69 | ///
70 | [Benchmark]
71 | public TestModel? PredicateParser()
72 | {
73 | var predicate = PredicateParser.Parse(Predicate).Compile();
74 |
75 | return _testModels.FirstOrDefault(predicate);
76 | }
77 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.DynamicPredicateParser/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 |
3 | BenchmarkRunner.Run(typeof(Program).Assembly);
--------------------------------------------------------------------------------
/src/main/Benchmarks.DynamicPredicateParser/TestModel.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.DynamicPredicateParser;
2 |
3 | public sealed class TestModel
4 | {
5 | public string Id { get; init; }
6 |
7 | public int Number { get; init; }
8 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.DynamicPredicateParser/readme.md:
--------------------------------------------------------------------------------
1 | ```
2 |
3 | BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.3880/23H2/2023Update/SunValley3)
4 | 13th Gen Intel Core i9-13905H, 1 CPU, 20 logical and 14 physical cores
5 | .NET SDK 8.0.100
6 | [Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
7 | DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
8 |
9 |
10 | ```
11 | | Method | GenerationSize | Mean | Error | StdDev | StdErr | Min | Q1 | Median | Q3 | Max | Op/s | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio |
12 | |-----------------|----------------|----------:|---------:|---------:|---------:|----------:|----------:|----------:|----------:|----------:|---------:|------:|--------:|-------:|-------:|----------:|------------:|
13 | | DynamicCore | 100 | 48.40 μs | 0.297 μs | 0.264 μs | 0.070 μs | 47.78 μs | 48.35 μs | 48.46 μs | 48.54 μs | 48.72 μs | 20,660.3 | 1.00 | 0.00 | 0.8545 | 0.7324 | 10.53 KB | 1.00 |
14 | | PredicateParser | 100 | 58.96 μs | 0.476 μs | 0.445 μs | 0.115 μs | 58.18 μs | 58.64 μs | 58.87 μs | 59.29 μs | 59.67 μs | 16,959.4 | 1.22 | 0.01 | 1.3428 | 1.2207 | 16.8 KB | 1.60 |
15 | | | | | | | | | | | | | | | | | | | |
16 | | DynamicCore | 1000 | 52.92 μs | 0.237 μs | 0.198 μs | 0.055 μs | 52.61 μs | 52.77 μs | 52.95 μs | 53.05 μs | 53.28 μs | 18,897.9 | 1.00 | 0.00 | 0.8545 | 0.7324 | 10.53 KB | 1.00 |
17 | | PredicateParser | 1000 | 77.43 μs | 0.672 μs | 0.628 μs | 0.162 μs | 75.91 μs | 77.15 μs | 77.57 μs | 77.83 μs | 78.26 μs | 12,914.8 | 1.47 | 0.01 | 1.2207 | 0.9766 | 16.8 KB | 1.60 |
18 | | | | | | | | | | | | | | | | | | | |
19 | | DynamicCore | 10000 | 84.19 μs | 1.638 μs | 2.012 μs | 0.429 μs | 81.12 μs | 82.54 μs | 84.49 μs | 85.82 μs | 87.00 μs | 11,878.4 | 1.00 | 0.00 | 0.7324 | 0.4883 | 10.52 KB | 1.00 |
20 | | PredicateParser | 10000 | 254.42 μs | 0.679 μs | 0.602 μs | 0.161 μs | 253.23 μs | 254.13 μs | 254.60 μs | 254.85 μs | 255.16 μs | 3,930.6 | 2.98 | 0.04 | 0.9766 | 0.4883 | 16.79 KB | 1.60 |
21 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/Benchmarks.Enum.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8
6 | enable
7 | enable
8 | Linux
9 |
10 |
11 |
12 |
13 | .dockerignore
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/Benchmarks/EnumBenchmarksBase.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using BenchmarkDotNet.Configs;
4 | using BenchmarkDotNet.Order;
5 |
6 | namespace Benchmarks.Enum.Benchmarks;
7 |
8 | ///
9 | /// Enum boxing/unboxing benchmarks base.
10 | ///
11 | [MemoryDiagnoser, MarkdownExporter, CategoriesColumn, AllStatisticsColumn, Orderer(SummaryOrderPolicy.FastestToSlowest),
12 | GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory), ExcludeFromCodeCoverage]
13 | public class EnumBenchmarksBase
14 | {
15 | ///
16 | /// Gets collection of enums.
17 | ///
18 | protected static TestEnum[] TestEnums { get; private set; } = default!;
19 |
20 | ///
21 | /// Global setup of private fields.
22 | ///
23 | [GlobalSetup]
24 | public void Setup()
25 | {
26 | TestEnums =
27 | [
28 | TestEnum.First,
29 | TestEnum.Second,
30 | TestEnum.Third,
31 | TestEnum.Fourth,
32 | TestEnum.Fifth,
33 | TestEnum.Sixth,
34 | TestEnum.Seventh,
35 | TestEnum.Eighth,
36 | TestEnum.Ninth,
37 | TestEnum.Tenth,
38 | TestEnum.Eleventh,
39 | TestEnum.Twelfth
40 | ];
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/Benchmarks/EnumNameBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using Benchmarks.Enum.Services;
4 |
5 | namespace Benchmarks.Enum.Benchmarks;
6 |
7 | ///
8 | /// Getting Name of Enum benchmarks.
9 | ///
10 | [ExcludeFromCodeCoverage]
11 | public class EnumNameBenchmarks : EnumBenchmarksBase
12 | {
13 | ///
14 | /// Getting string enum name by .ToString(). (Boxing allocation).
15 | ///
16 | /// value.
17 | [BenchmarkCategory(Group.Name), Benchmark]
18 | public string DefaultToString()
19 | {
20 | return TestEnums[0].DefaultToString();
21 | }
22 |
23 | ///
24 | /// Getting string enum name by Enum.GetName().
25 | ///
26 | /// value.
27 | [BenchmarkCategory(Group.Name), Benchmark]
28 | public string? EnumGetName()
29 | {
30 | return TestEnums[0].EnumGetName();
31 | }
32 |
33 | ///
34 | /// Getting string enum name by written custom method.
35 | ///
36 | /// value.
37 | [BenchmarkCategory(Group.Name), Benchmark]
38 | public string CustomGetName()
39 | {
40 | return TestEnums[0].CustomGetName();
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/Benchmarks/EnumValueBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using Benchmarks.Enum.Services;
4 |
5 | namespace Benchmarks.Enum.Benchmarks;
6 |
7 | ///
8 | /// Benchmarks of getting int value from enum.
9 | ///
10 | [ExcludeFromCodeCoverage]
11 | public class EnumValueBenchmarks : EnumBenchmarksBase
12 | {
13 | ///
14 | /// Getting int value from enum by .ToString().
15 | ///
16 | [BenchmarkCategory(Group.Value), Benchmark]
17 | public string ToStringFormatD()
18 | {
19 | return TestEnums[0].ToStringFormatD();
20 | }
21 |
22 | ///
23 | /// Getting int value from enum by implicit cast of enum
24 | ///
25 | [BenchmarkCategory(Group.Value), Benchmark]
26 | public string IntCastToString()
27 | {
28 | return TestEnums[0].IntCastToString();
29 | }
30 |
31 | ///
32 | /// Getting int value from enum by custom method
33 | ///
34 | [BenchmarkCategory(Group.Value), Benchmark]
35 | public string ExternalMethodToString()
36 | {
37 | return TestEnums[0].CustomGetValue();
38 | }
39 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
2 | USER $APP_UID
3 | WORKDIR /app
4 |
5 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 | ARG BUILD_CONFIGURATION=Release
7 | WORKDIR /src
8 | COPY ["Benchmark.Enum/Benchmark.Enum.csproj", "Benchmark.Enum/"]
9 | RUN dotnet restore "Benchmark.Enum/Benchmark.Enum.csproj"
10 | COPY . .
11 | WORKDIR "/src/Benchmark.Enum"
12 | RUN dotnet build "Benchmark.Enum.csproj" -c $BUILD_CONFIGURATION -o /app/build
13 |
14 | FROM build AS publish
15 | ARG BUILD_CONFIGURATION=Release
16 | RUN dotnet publish "Benchmark.Enum.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
17 |
18 | FROM base AS final
19 | WORKDIR /app
20 | COPY --from=publish /app/publish .
21 | ENTRYPOINT ["dotnet", "Benchmark.Enum.dll"]
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/Extensions/EnumExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Enum.Extensions;
2 |
3 | ///
4 | /// Enum extensions.
5 | ///
6 | internal static class EnumExtensions
7 | {
8 | ///
9 | /// The simplest method to get name of the enum.
10 | ///
11 | /// .
12 | /// input enum name.
13 | /// If out of range of enum.
14 | internal static string GetName(this TestEnum testEnum)
15 | {
16 | return testEnum switch
17 | {
18 | TestEnum.First => nameof(TestEnum.First),
19 | TestEnum.Second => nameof(TestEnum.Second),
20 | TestEnum.Third => nameof(TestEnum.Third),
21 | TestEnum.Fourth => nameof(TestEnum.Fourth),
22 | TestEnum.Fifth => nameof(TestEnum.Fifth),
23 | TestEnum.Sixth => nameof(TestEnum.Sixth),
24 | TestEnum.Seventh => nameof(TestEnum.Seventh),
25 | TestEnum.Eighth => nameof(TestEnum.Eighth),
26 | TestEnum.Ninth => nameof(TestEnum.Ninth),
27 | TestEnum.Tenth => nameof(TestEnum.Tenth),
28 | TestEnum.Eleventh => nameof(TestEnum.Eleventh),
29 | TestEnum.Twelfth => nameof(TestEnum.Twelfth),
30 | TestEnum.Zero => nameof(TestEnum.Zero),
31 | _ => throw new ArgumentOutOfRangeException(nameof(testEnum), testEnum, default)
32 | };
33 | }
34 |
35 | ///
36 | /// The simplest method to get name of the enum.
37 | ///
38 | /// .
39 | /// input enum name.
40 | /// If out of range of enum.
41 | internal static byte GetValue(this TestEnum testEnum)
42 | {
43 | return testEnum switch
44 | {
45 | TestEnum.First => 1,
46 | TestEnum.Second => 2,
47 | TestEnum.Third => 3,
48 | TestEnum.Fourth => 4,
49 | TestEnum.Fifth => 5,
50 | TestEnum.Sixth => 6,
51 | TestEnum.Seventh => 7,
52 | TestEnum.Eighth => 8,
53 | TestEnum.Ninth => 9,
54 | TestEnum.Tenth => 10,
55 | TestEnum.Eleventh => 11,
56 | TestEnum.Twelfth => 12,
57 | TestEnum.Zero => 0,
58 | _ => throw new ArgumentOutOfRangeException(nameof(testEnum), testEnum, default)
59 | };
60 | }
61 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/Group.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Enum;
2 |
3 | ///
4 | /// Special constants class for splitting results into groups.
5 | ///
6 | internal static class Group
7 | {
8 | internal const string Name = "Get Enum Name";
9 |
10 | internal const string Value = "Get Enum Value";
11 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 |
3 | BenchmarkRunner.Run(typeof(Program).Assembly);
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/Services/EnumNameService.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Enum.Extensions;
2 |
3 | namespace Benchmarks.Enum.Services;
4 |
5 | ///
6 | /// Enum getting name service for benchmarks and unit testing.
7 | ///
8 | public static class EnumNameService
9 | {
10 | ///
11 | /// Gets enum name by using default 'ToString' method.
12 | ///
13 | /// Note: Boxing allocation: inherited 'System.Object' virtual method call on value type instance.
14 | ///
15 | ///
16 | /// .
17 | /// Name of Enum.
18 | public static string DefaultToString(this TestEnum testEnum)
19 | {
20 | return testEnum.ToString();
21 | }
22 |
23 | ///
24 | /// Gets enum name by using default extensions method of class
25 | ///
26 | /// .
27 | /// Name of Enum.
28 | public static string? EnumGetName(this TestEnum testEnum)
29 | {
30 | return System.Enum.GetName(testEnum);
31 | }
32 |
33 | ///
34 | /// Gets enum name by using custom-made method from .
35 | ///
36 | /// .
37 | /// Name of Enum.
38 | public static string CustomGetName(this TestEnum testEnum)
39 | {
40 | return testEnum.GetName();
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/Services/EnumValueService.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Enum.Extensions;
2 |
3 | namespace Benchmarks.Enum.Services;
4 |
5 | ///
6 | /// Enum getting value service for benchmarks and unit testing.
7 | ///
8 | public static class EnumValueService
9 | {
10 | ///
11 | /// Getting integer value from enum using default method 'ToString' with format 'D - integer value'.
12 | ///
13 | /// .
14 | /// Value of Enum.
15 | public static string ToStringFormatD(this TestEnum testEnum)
16 | {
17 | return testEnum.ToString("D");
18 | }
19 |
20 | ///
21 | /// Getting integer value from enum by casting firstly to and then using
22 | /// 'ToString'.
23 | ///
24 | /// .
25 | /// Value of Enum.
26 | public static string IntCastToString(this TestEnum testEnum)
27 | {
28 | return ((int)testEnum).ToString();
29 | }
30 |
31 | ///
32 | /// Getting integer value from enum using method from to get int value
33 | /// .
34 | ///
35 | /// .
36 | /// Value of Enum.
37 | public static string CustomGetValue(this TestEnum testEnum)
38 | {
39 | return testEnum.GetValue().ToString();
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Enum/TestEnum.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Enum;
2 |
3 | ///
4 | /// Test enum entity.
5 | ///
6 | public enum TestEnum
7 | {
8 | ///
9 | /// Zero.
10 | ///
11 | Zero = 0,
12 |
13 | ///
14 | /// First.
15 | ///
16 | First = 1,
17 |
18 | ///
19 | /// Second.
20 | ///
21 | Second = 2,
22 |
23 | ///
24 | /// Third.
25 | ///
26 | Third = 3,
27 |
28 | ///
29 | /// Fourth.
30 | ///
31 | Fourth = 4,
32 |
33 | ///
34 | /// Fifth.
35 | ///
36 | Fifth = 5,
37 |
38 | ///
39 | /// Sixth.
40 | ///
41 | Sixth = 6,
42 |
43 | ///
44 | /// Seventh.
45 | ///
46 | Seventh = 7,
47 |
48 | ///
49 | /// Eighth.
50 | ///
51 | Eighth = 8,
52 |
53 | ///
54 | /// Ninth.
55 | ///
56 | Ninth = 9,
57 |
58 | ///
59 | /// Tenth.
60 | ///
61 | Tenth = 10,
62 |
63 | ///
64 | /// Eleventh.
65 | ///
66 | Eleventh = 11,
67 |
68 | ///
69 | /// Twelfth.
70 | ///
71 | Twelfth = 12
72 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Flattening/Benchmarks.Flattening.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Flattening/InternalModel.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Flattening;
2 |
3 | public sealed class InternalModel
4 | {
5 | public string? Address { get; init; }
6 |
7 | public string? City { get; init; }
8 |
9 | public string? Country { get; init; }
10 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Flattening/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 |
3 | namespace Benchmarks.Flattening;
4 |
5 | internal static class Program
6 | {
7 | public static void Main(string[] args)
8 | {
9 | BenchmarkRunner.Run(typeof(Program).Assembly);
10 | }
11 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Flattening/README.MD:
--------------------------------------------------------------------------------
1 | ```
2 |
3 | BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.3194)
4 | Unknown processor
5 | .NET SDK 9.0.100
6 | [Host] : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX2
7 | DefaultJob : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX2
8 |
9 | ```
10 |
11 | | Method | Mean | Error | StdDev | StdErr | Min | Q1 | Median | Q3 | Max | Op/s | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio |
12 | |----------------------------------|---------:|--------:|--------:|--------:|---------:|---------:|---------:|---------:|---------:|------------:|------:|--------:|-------:|----------:|------------:|
13 | | 'ToFlat direct model' | 151.8 ns | 0.81 ns | 0.76 ns | 0.20 ns | 150.5 ns | 151.4 ns | 151.8 ns | 152.2 ns | 153.1 ns | 6,587,404.6 | 1.00 | 0.01 | 0.0408 | 512 B | 1.00 |
14 | | 'ToFlat with reflection' | 326.8 ns | 2.16 ns | 2.02 ns | 0.52 ns | 322.4 ns | 325.5 ns | 327.1 ns | 328.0 ns | 330.5 ns | 3,059,850.7 | 2.15 | 0.02 | 0.0668 | 840 B | 1.64 |
15 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Flattening/UnflatModel.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Flattening;
2 |
3 | public sealed class UnflatModel
4 | {
5 | public string? Email { get; init; }
6 |
7 | public bool? IsEmailConfirmed { get; init; }
8 |
9 | public bool? IsPhoneConfirmed { get; init; }
10 |
11 | public InternalModel? InternalModel { get; init; }
12 |
13 | public string? Phone { get; init; }
14 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.GroupByVsDistinct/Benchmarks.GroupByVsDistinct.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8
6 | enable
7 | enable
8 | Linux
9 |
10 |
11 |
12 |
13 | .dockerignore
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.GroupByVsDistinct/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
2 | USER $APP_UID
3 | WORKDIR /app
4 |
5 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 | ARG BUILD_CONFIGURATION=Release
7 | WORKDIR /src
8 | COPY ["src/main/Benchmark.GroupByVsDistinct/Benchmark.GroupByVsDistinct.csproj", "src/main/Benchmark.GroupByVsDistinct/"]
9 | RUN dotnet restore "src/main/Benchmark.GroupByVsDistinct/Benchmark.GroupByVsDistinct.csproj"
10 | COPY . .
11 | WORKDIR "/src/src/main/Benchmark.GroupByVsDistinct"
12 | RUN dotnet build "Benchmark.GroupByVsDistinct.csproj" -c $BUILD_CONFIGURATION -o /app/build
13 |
14 | FROM build AS publish
15 | ARG BUILD_CONFIGURATION=Release
16 | RUN dotnet publish "Benchmark.GroupByVsDistinct.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
17 |
18 | FROM base AS final
19 | WORKDIR /app
20 | COPY --from=publish /app/publish .
21 | ENTRYPOINT ["dotnet", "Benchmark.GroupByVsDistinct.dll"]
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.GroupByVsDistinct/Models/InnerModel.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 |
3 | namespace Benchmarks.GroupByVsDistinct.Models;
4 |
5 | ///
6 | /// Inner test class of test class.
7 | ///
8 | [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
9 | public sealed class InnerModel
10 | {
11 | ///
12 | /// Id of inner test model.
13 | ///
14 | public string InnerId { get; init; } = string.Empty;
15 |
16 | ///
17 | /// Date
18 | ///
19 | public DateTime DateOnly { get; init; } = DateTime.Now;
20 |
21 | ///
22 | /// Test int value.
23 | ///
24 | public int Integer { get; init; }
25 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.GroupByVsDistinct/Models/SimpleModel.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 |
3 | namespace Benchmarks.GroupByVsDistinct.Models;
4 |
5 | ///
6 | /// Test model.
7 | ///
8 | [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
9 | public sealed class SimpleModel
10 | {
11 | ///
12 | /// Id of test model.
13 | ///
14 | public string TestModelId { get; set; } = string.Empty;
15 |
16 | ///
17 | /// Id of inner test model.
18 | ///
19 | public string InnerTestModelId { get; set; } = string.Empty;
20 |
21 | ///
22 | /// Test Date.
23 | ///
24 | public DateTime DateOnly { get; set; } = DateTime.Now;
25 |
26 | ///
27 | /// Test int value.
28 | ///
29 | public int Integer { get; set; }
30 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.GroupByVsDistinct/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 |
3 | BenchmarkRunner.Run(typeof(Program).Assembly);
--------------------------------------------------------------------------------
/src/main/Benchmarks.GroupByVsDistinct/Services/LinqService.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.GroupByVsDistinct.Models;
2 |
3 | namespace Benchmarks.GroupByVsDistinct.Services;
4 |
5 | ///
6 | /// Linq methods testing service.
7 | ///
8 | public static class LinqService
9 | {
10 | ///
11 | /// Gets collection of using GroupBy and Select methods.
12 | ///
13 | /// collection.
14 | /// Dictionary of value with key as string.
15 | /// Specific string id, to be retrieved by.
16 | /// Collection of .
17 | public static IEnumerable GroupByTake(
18 | this IEnumerable testModelsList, Dictionary innerTestModels, string innerTestModelConstId)
19 | {
20 | return testModelsList
21 | .GroupBy(x => x.InnerTestModelId)
22 | .Select(_ => innerTestModels[innerTestModelConstId]);
23 | }
24 |
25 | ///
26 | /// Gets collection of using DistinctBy and Select methods.
27 | ///
28 | /// collection.
29 | /// Dictionary of value with key as string.
30 | /// Specific string id, to be retrieved by.
31 | /// Collection of .
32 | public static IEnumerable DistinctByTake(
33 | this IEnumerable testModelsList, Dictionary innerTestModels, string innerTestModelConstId)
34 | {
35 | return testModelsList
36 | .DistinctBy(x => x.InnerTestModelId)
37 | .Select(_ => innerTestModels[innerTestModelConstId]);
38 | }
39 |
40 | ///
41 | /// Gets collection of using Select, then Distinct and then Select methods.
42 | ///
43 | /// collection.
44 | /// Dictionary of value with key as string.
45 | /// Specific string id, to be retrieved by.
46 | /// Collection of .
47 | public static IEnumerable DistinctTake(
48 | this IEnumerable testModelsList, Dictionary innerTestModels, string innerTestModelConstId)
49 | {
50 | return testModelsList
51 | .Select(x => x.InnerTestModelId)
52 | .Distinct()
53 | .Select(_ => innerTestModels[innerTestModelConstId]);
54 | }
55 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Benchmarks.Iterators.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8
6 | enable
7 | enable
8 | Linux
9 |
10 |
11 |
12 |
13 | .dockerignore
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | IterationService.cs
24 |
25 |
26 | IterationService.cs
27 |
28 |
29 | IterationService.cs
30 |
31 |
32 | IteratorBenchmarks.cs
33 |
34 |
35 | IteratorBenchmarks.cs
36 |
37 |
38 | IteratorBenchmarks.cs
39 |
40 |
41 | IteratorBenchmarks.cs
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Benchmarks/BenchmarksBase.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using BenchmarkDotNet.Configs;
4 | using BenchmarkDotNet.Engines;
5 | using BenchmarkDotNet.Order;
6 | using Benchmarks.Iterators.Models;
7 | using Bogus;
8 |
9 | namespace Benchmarks.Iterators.Benchmarks;
10 |
11 | ///
12 | /// Base class for iterators benchmarks.
13 | ///
14 | [MemoryDiagnoser, AllStatisticsColumn, CategoriesColumn, MarkdownExporterAttribute.GitHub, Orderer(SummaryOrderPolicy.FastestToSlowest),
15 | GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory), ExcludeFromCodeCoverage]
16 | public class BenchmarksBase
17 | {
18 | ///
19 | /// .
20 | ///
21 | protected readonly Consumer Consumer = new();
22 |
23 | ///
24 | /// Array of int.
25 | ///
26 | protected int[] TestArray = default!;
27 |
28 | ///
29 | /// Collection of int as array
30 | ///
31 | protected ICollection TestCollectionArray = default!;
32 |
33 | ///
34 | /// Collection of int as list
35 | ///
36 | protected ICollection TestCollectionList = default!;
37 |
38 | ///
39 | /// List of .
40 | ///
41 | protected List TestInputModels = default!;
42 |
43 | ///
44 | /// List of int.
45 | ///
46 | protected List TestList = default!;
47 |
48 | ///
49 | /// Parameter for models count.
50 | /// **NOTE:** Intentionally left public for BenchmarkDotNet Params.
51 | ///
52 | [Params(10, 100000)]
53 | public int Size { get; set; }
54 |
55 | ///
56 | /// Global setup of private and protected parameters.
57 | ///
58 | [GlobalSetup]
59 | public void Setup()
60 | {
61 | var faker = new Faker();
62 | Randomizer.Seed = new Random(420);
63 |
64 | TestInputModels = faker
65 | .RuleFor(testModel => testModel.TestInd, fakerSetter => fakerSetter.Random.Int(-100000, 100000))
66 | .RuleFor(testModel => testModel.TestString, fakerSetter => fakerSetter.Random.String2(10))
67 | .RuleFor(testModel => testModel.TestDateTime, fakerSetter => fakerSetter.Date.Past())
68 | .Generate(Size)!;
69 |
70 | TestArray = TestInputModels.Select(model => model.TestInd).ToArray();
71 | TestList = TestInputModels.Select(model => model.TestInd).ToList();
72 | TestCollectionArray = TestInputModels.Select(model => model.TestInd).ToArray();
73 | TestCollectionList = TestInputModels.Select(model => model.TestInd).ToList();
74 | }
75 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Benchmarks/IteratorBenchmarks.Array.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Attributes;
2 | using Benchmarks.Iterators.Services;
3 |
4 | namespace Benchmarks.Iterators.Benchmarks;
5 |
6 | public partial class IteratorBenchmarks
7 | {
8 | ///
9 | /// Testing with 'for' method.
10 | ///
11 | [BenchmarkCategory(Group.Array), Benchmark(Description = "For")]
12 | public int ForArray()
13 | {
14 | return TestArray.For();
15 | }
16 |
17 | ///
18 | /// Testing with 'Foreach' method.
19 | ///
20 | [BenchmarkCategory(Group.Array), Benchmark(Description = "Foreach")]
21 | public int ForeachArray()
22 | {
23 | return TestArray.Foreach();
24 | }
25 |
26 | ///
27 | /// Testing with 'Linq.Aggregate' methods.
28 | ///
29 | [BenchmarkCategory(Group.Array), Benchmark(Description = "Linq Aggregate")]
30 | public int? LinqArray()
31 | {
32 | return TestArray.LinqAggregate();
33 | }
34 |
35 | ///
36 | /// Testing with 'Linq.Sum' methods.
37 | ///
38 | [BenchmarkCategory(Group.Array), Benchmark(Description = "Linq Sum")]
39 | public int? SumArray()
40 | {
41 | return TestArray.LinqSum();
42 | }
43 |
44 | ///
45 | /// Testing with 'foreach(ref)' methods.
46 | ///
47 | [BenchmarkCategory(Group.Array), Benchmark(Description = "Ref Foreach")]
48 | public int RefForeachArray()
49 | {
50 | return TestArray.RefForeach();
51 | }
52 |
53 | ///
54 | /// Testing with '.AsSpan + for' methods.
55 | ///
56 | [BenchmarkCategory(Group.Array), Benchmark(Description = "AsSpan + For")]
57 | public int SpanForArray()
58 | {
59 | return TestArray.SpanFor();
60 | }
61 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Benchmarks/IteratorBenchmarks.ICollection.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Attributes;
2 | using Benchmarks.Iterators.Services;
3 |
4 | namespace Benchmarks.Iterators.Benchmarks;
5 |
6 | public partial class IteratorBenchmarks
7 | {
8 | ///
9 | /// Testing with 'Foreach' method.
10 | ///
11 | [BenchmarkCategory(Group.Collection), Benchmark(Description = "Foreach. Array as ICollection")]
12 | public int ForeachICollectionArray()
13 | {
14 | return TestCollectionArray.Foreach();
15 | }
16 |
17 | ///
18 | /// Testing with 'Linq.Aggregate' methods.
19 | ///
20 | [BenchmarkCategory(Group.Collection), Benchmark(Description = "Linq Aggregate. Array as ICollection")]
21 | public int? LinqICollectionArray()
22 | {
23 | return TestCollectionArray.LinqAggregate();
24 | }
25 |
26 | ///
27 | /// Testing with 'Linq.Sum' methods.
28 | ///
29 | [BenchmarkCategory(Group.Collection), Benchmark(Description = "Linq Sum. Array as ICollection")]
30 | public int? SumICollectionArray()
31 | {
32 | return TestCollectionArray.LinqSum();
33 | }
34 |
35 | ///
36 | /// Testing with 'Foreach' method.
37 | ///
38 | [BenchmarkCategory(Group.Collection), Benchmark(Description = "Foreach. List as ICollection")]
39 | public int ForeachICollectionList()
40 | {
41 | return TestCollectionList.Foreach();
42 | }
43 |
44 | ///
45 | /// Testing with 'Linq.Aggregate' methods.
46 | ///
47 | [BenchmarkCategory(Group.Collection), Benchmark(Description = "Linq Aggregate. List as ICollection")]
48 | public int? LinqICollectionList()
49 | {
50 | return TestCollectionList.LinqAggregate();
51 | }
52 |
53 | ///
54 | /// Testing with 'Linq.Sum' methods.
55 | ///
56 | [BenchmarkCategory(Group.Collection), Benchmark(Description = "Linq Sum. List as ICollection")]
57 | public int? SumICollectionList()
58 | {
59 | return TestCollectionList.LinqSum();
60 | }
61 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Benchmarks/IteratorBenchmarks.List.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Attributes;
2 | using Benchmarks.Iterators.Services;
3 |
4 | namespace Benchmarks.Iterators.Benchmarks;
5 |
6 | public partial class IteratorBenchmarks
7 | {
8 | ///
9 | /// Testing with 'for' method.
10 | ///
11 | [BenchmarkCategory(Group.List), Benchmark(Description = "For", Baseline = true)]
12 | public int ForList()
13 | {
14 | return TestList.For();
15 | }
16 |
17 | ///
18 | /// Testing with 'Foreach' method.
19 | ///
20 | [BenchmarkCategory(Group.List), Benchmark(Description = "Foreach")]
21 | public int ForeachList()
22 | {
23 | return TestList.Foreach();
24 | }
25 |
26 | ///
27 | /// Testing with 'Linq.Aggregate' methods.
28 | ///
29 | [BenchmarkCategory(Group.List), Benchmark(Description = "Linq Aggregate")]
30 | public int? LinqList()
31 | {
32 | return TestList.LinqAggregate();
33 | }
34 |
35 | ///
36 | /// Testing with 'Linq.Sum' methods.
37 | ///
38 | [BenchmarkCategory(Group.List), Benchmark(Description = "Linq Sum")]
39 | public int? SumList()
40 | {
41 | return TestList.LinqSum();
42 | }
43 |
44 | ///
45 | /// Testing with 'foreach(ref)' methods.
46 | ///
47 | [BenchmarkCategory(Group.List), Benchmark(Description = "Ref Foreach")]
48 | public int RefForeachList()
49 | {
50 | return TestList.RefForeach();
51 | }
52 |
53 | ///
54 | /// Testing with '.AsSpan + for' methods.
55 | ///
56 | [BenchmarkCategory(Group.List), Benchmark(Description = "AsSpan + For")]
57 | public int SpanForList()
58 | {
59 | return TestList.SpanFor();
60 | }
61 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Benchmarks/IteratorBenchmarks.Serializing.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Attributes;
2 | using BenchmarkDotNet.Engines;
3 | using Benchmarks.Iterators.Models;
4 | using Benchmarks.Iterators.Services;
5 |
6 | namespace Benchmarks.Iterators.Benchmarks;
7 |
8 | ///
9 | public partial class IteratorBenchmarks
10 | {
11 | ///
12 | /// Testing with 'for' method.
13 | ///
14 | [BenchmarkCategory(Group.Serializing), Benchmark(Description = $"For serialization {nameof(SimpleModel)}", Baseline = true)]
15 | public void For()
16 | {
17 | TestInputModels.For().Consume(Consumer);
18 | }
19 |
20 | ///
21 | /// Testing with 'for' method.
22 | ///
23 | [BenchmarkCategory(Group.Serializing), Benchmark(Description = $"ArrayPool + For serialization {nameof(SimpleModel)}")]
24 | public void ForArrayPool()
25 | {
26 | TestInputModels.ForArrayPool().Consume(Consumer);
27 | }
28 |
29 | ///
30 | /// Testing with 'Foreach' method.
31 | ///
32 | [BenchmarkCategory(Group.Serializing), Benchmark(Description = $"Foreach serialization {nameof(SimpleModel)}")]
33 | public void Foreach()
34 | {
35 | TestInputModels.Foreach().Consume(Consumer);
36 | }
37 |
38 | ///
39 | /// Testing with 'Linq' methods.
40 | ///
41 | [BenchmarkCategory(Group.Serializing), Benchmark(Description = $"Linq serialization {nameof(SimpleModel)}")]
42 | public void Linq()
43 | {
44 | TestInputModels.Linq().Consume(Consumer);
45 | }
46 |
47 | ///
48 | /// Testing with 'Yield' methods.
49 | ///
50 | [BenchmarkCategory(Group.Serializing), Benchmark(Description = $"Yield serialization {nameof(SimpleModel)}")]
51 | public void Yield()
52 | {
53 | TestInputModels.Yield().Consume(Consumer);
54 | }
55 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Benchmarks/IteratorBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 |
3 | namespace Benchmarks.Iterators.Benchmarks;
4 |
5 | [ExcludeFromCodeCoverage]
6 | public partial class IteratorBenchmarks : BenchmarksBase;
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
2 | USER $APP_UID
3 | WORKDIR /app
4 |
5 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 | ARG BUILD_CONFIGURATION=Release
7 | WORKDIR /src
8 | COPY ["src/main/Benchmark.Iterators/Benchmark.Iterators.csproj", "src/main/Benchmark.Iterators/"]
9 | RUN dotnet restore "src/main/Benchmark.Iterators/Benchmark.Iterators.csproj"
10 | COPY . .
11 | WORKDIR "/src/src/main/Benchmark.Iterators"
12 | RUN dotnet build "Benchmark.Iterators.csproj" -c $BUILD_CONFIGURATION -o /app/build
13 |
14 | FROM build AS publish
15 | ARG BUILD_CONFIGURATION=Release
16 | RUN dotnet publish "Benchmark.Iterators.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
17 |
18 | FROM base AS final
19 | WORKDIR /app
20 | COPY --from=publish /app/publish .
21 | ENTRYPOINT ["dotnet", "Benchmark.Iterators.dll"]
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Group.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Iterators;
2 |
3 | internal static class Group
4 | {
5 | internal const string List = "List";
6 |
7 | internal const string Array = "Array";
8 |
9 | internal const string Collection = "ICollection";
10 |
11 | internal const string Serializing = "Serializing model";
12 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Models/SimpleModel.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Iterators.Models;
2 |
3 | ///
4 | /// Test model class.
5 | ///
6 | public sealed class SimpleModel
7 | {
8 | ///
9 | /// Test id.
10 | ///
11 | public int TestInd { get; set; }
12 |
13 | ///
14 | /// Test string.
15 | ///
16 | public string? TestString { get; set; }
17 |
18 | ///
19 | /// Test date time.
20 | ///
21 | public DateTime? TestDateTime { get; set; }
22 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 |
3 | BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run();
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Services/IterationService.Array.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Iterators.Services;
2 |
3 | /// .
4 | public static partial class IterationService
5 | {
6 | ///
7 | /// Testing with 'for' method.
8 | ///
9 | public static int For(this int[] inputArray)
10 | {
11 | var sumResult = 0;
12 |
13 | for (var i = 0; i < inputArray.Length; i++)
14 | {
15 | sumResult += inputArray[i];
16 | }
17 |
18 | return sumResult;
19 | }
20 |
21 | ///
22 | /// Testing with 'Foreach' method.
23 | ///
24 | public static int Foreach(this int[] inputArray)
25 | {
26 | var sumResult = 0;
27 |
28 | foreach (var testModel in inputArray) sumResult += testModel;
29 |
30 | return sumResult;
31 | }
32 |
33 | ///
34 | /// Testing with 'Linq' methods.
35 | ///
36 | public static int? LinqAggregate(this int[] inputArray)
37 | {
38 | return inputArray.Aggregate((a, b) => a + b);
39 | }
40 |
41 | ///
42 | /// Testing with 'Linq' methods.
43 | ///
44 | public static int? LinqSum(this int[] inputArray)
45 | {
46 | return inputArray.Sum();
47 | }
48 |
49 | ///
50 | /// Testing with 'Ref Foreach' methods.
51 | ///
52 | public static int RefForeach(this int[] inputArray)
53 | {
54 | var sumResult = 0;
55 |
56 | foreach (ref var input in inputArray.AsSpan()) sumResult += input;
57 |
58 | return sumResult;
59 | }
60 |
61 | ///
62 | /// Testing with 'Span For' methods.
63 | ///
64 | public static int SpanFor(this int[] inputArray)
65 | {
66 | var sumResult = 0;
67 |
68 | var array = inputArray.AsSpan();
69 |
70 | for (var i = 0; i < array.Length; i++)
71 | {
72 | sumResult += inputArray[i];
73 | }
74 |
75 | return sumResult;
76 | }
77 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Services/IterationService.Collection.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Iterators.Services;
2 |
3 | ///
4 | /// .
5 | public static partial class IterationService
6 | {
7 | ///
8 | /// Testing with 'Foreach' method.
9 | ///
10 | public static int Foreach(this ICollection inputCollection)
11 | {
12 | var sumResult = 0;
13 |
14 | foreach (var testModel in inputCollection) sumResult += testModel;
15 |
16 | return sumResult;
17 | }
18 |
19 | ///
20 | /// Testing with 'Linq' methods.
21 | ///
22 | public static int? LinqAggregate(this ICollection inputCollection)
23 | {
24 | return inputCollection.Aggregate((a, b) => a + b);
25 | }
26 |
27 | ///
28 | /// Testing with 'Linq' methods.
29 | ///
30 | public static int? LinqSum(this ICollection inputCollection)
31 | {
32 | return inputCollection.Sum();
33 | }
34 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Services/IterationService.List.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace Benchmarks.Iterators.Services;
4 |
5 | ///
6 | /// .
7 | public static partial class IterationService
8 | {
9 | ///
10 | /// Testing with 'for' method.
11 | ///
12 | public static int For(this List inputList)
13 | {
14 | var sumResult = 0;
15 |
16 | for (var i = 0; i < inputList.Count; i++)
17 | {
18 | sumResult += inputList[i];
19 | }
20 |
21 | return sumResult;
22 | }
23 |
24 | ///
25 | /// Testing with 'Foreach' method.
26 | ///
27 | public static int Foreach(this List inputList)
28 | {
29 | var sumResult = 0;
30 |
31 | foreach (var testModel in inputList) sumResult += testModel;
32 |
33 | return sumResult;
34 | }
35 |
36 | ///
37 | /// Testing with 'Linq' methods.
38 | ///
39 | public static int? LinqAggregate(this List inputList)
40 | {
41 | return inputList.Aggregate((a, b) => a + b);
42 | }
43 |
44 | ///
45 | /// Testing with 'Linq' methods.
46 | ///
47 | public static int? LinqSum(this List inputList)
48 | {
49 | return inputList.Sum();
50 | }
51 |
52 | ///
53 | /// Testing with 'Ref Foreach' methods.
54 | ///
55 | public static int RefForeach(this List inputList)
56 | {
57 | var sumResult = 0;
58 |
59 | foreach (ref var input in CollectionsMarshal.AsSpan(inputList)) sumResult += input;
60 |
61 | return sumResult;
62 | }
63 |
64 | ///
65 | /// Testing with 'Span For' methods.
66 | ///
67 | public static int SpanFor(this List inputList)
68 | {
69 | var sumResult = 0;
70 |
71 | var array = CollectionsMarshal.AsSpan(inputList);
72 |
73 | for (var i = 0; i < array.Length; i++)
74 | {
75 | sumResult += inputList[i];
76 | }
77 |
78 | return sumResult;
79 | }
80 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Iterators/Services/IterationService.cs:
--------------------------------------------------------------------------------
1 | using System.Buffers;
2 | using System.Text.Json;
3 | using Benchmarks.Iterators.Models;
4 |
5 | namespace Benchmarks.Iterators.Services;
6 |
7 | ///
8 | /// Iteration service. Made static for faster development
9 | ///
10 | public static partial class IterationService
11 | {
12 | ///
13 | /// Testing with 'for' method.
14 | ///
15 | ///
16 | public static string[] For(this List testInputModels)
17 | {
18 | var testOutputModels = new string[testInputModels.Count];
19 |
20 | for (var i = 0; i < testInputModels.Count; i++)
21 | {
22 | if (testInputModels[i] is null) continue;
23 |
24 | testOutputModels[i] = JsonSerializer.Serialize(testInputModels[i]);
25 | }
26 |
27 | return testOutputModels;
28 | }
29 |
30 | ///
31 | /// Testing with 'for' method.
32 | ///
33 | ///
34 | public static string[] ForArrayPool(this List testInputModels)
35 | {
36 | var pooledArray = ArrayPool.Shared.Rent(testInputModels.Count);
37 |
38 | try
39 | {
40 | Span spanArray = pooledArray;
41 |
42 | var index = 0;
43 |
44 | while (index < testInputModels.Count)
45 | {
46 | if (testInputModels[index] is null)
47 | {
48 | index++;
49 | continue;
50 | }
51 |
52 | spanArray[index] = JsonSerializer.Serialize(testInputModels[index]);
53 | index++;
54 | }
55 |
56 | return spanArray[..index].ToArray();
57 | }
58 | finally
59 | {
60 | ArrayPool.Shared.Return(pooledArray);
61 | }
62 | }
63 |
64 | ///
65 | /// Testing with 'for' method.
66 | ///
67 | ///
68 | public static IEnumerable Yield(this List testInputModels)
69 | {
70 | foreach (var testModel in testInputModels)
71 | {
72 | if (testModel is null) continue;
73 |
74 | yield return JsonSerializer.Serialize(testModel);
75 | }
76 | }
77 |
78 | ///
79 | /// Testing with 'Foreach' method.
80 | ///
81 | public static List Foreach(this List testInputModels)
82 | {
83 | var testOutputModels = new List(testInputModels.Count);
84 |
85 | foreach (var testModel in testInputModels)
86 | {
87 | if (testModel is null) continue;
88 |
89 | testOutputModels.Add(JsonSerializer.Serialize(testModel));
90 | }
91 |
92 | return testOutputModels;
93 | }
94 |
95 | ///
96 | /// Testing with 'Linq' methods.
97 | ///
98 | public static IEnumerable Linq(this IEnumerable testInputModels)
99 | {
100 | return testInputModels
101 | .Where(testModel => testModel is not null)
102 | .Select(testModel => JsonSerializer.Serialize(testModel));
103 | }
104 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.QueryBuilder/Benchmarks.QueryBuilder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8
6 | enable
7 | enable
8 | Linux
9 | true
10 |
11 |
12 |
13 |
14 | .dockerignore
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.QueryBuilder/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
2 | USER $APP_UID
3 | WORKDIR /app
4 |
5 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 | ARG BUILD_CONFIGURATION=Release
7 | WORKDIR /src
8 | COPY ["src/main/Benchmark.QueryBuilder/Benchmark.QueryBuilder.csproj", "src/main/Benchmark.QueryBuilder/"]
9 | RUN dotnet restore "src/main/Benchmark.QueryBuilder/Benchmark.QueryBuilder.csproj"
10 | COPY . .
11 | WORKDIR "/src/src/main/Benchmark.QueryBuilder"
12 | RUN dotnet build "Benchmark.QueryBuilder.csproj" -c $BUILD_CONFIGURATION -o /app/build
13 |
14 | FROM build AS publish
15 | ARG BUILD_CONFIGURATION=Release
16 | RUN dotnet publish "Benchmark.QueryBuilder.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
17 |
18 | FROM base AS final
19 | WORKDIR /app
20 | COPY --from=publish /app/publish .
21 | ENTRYPOINT ["dotnet", "Benchmark.QueryBuilder.dll"]
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.QueryBuilder/Group.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.QueryBuilder;
2 |
3 | internal static class Group
4 | {
5 | internal const string StringUrl = "String Url";
6 |
7 | internal const string UriUrl = "Uri Url";
8 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.QueryBuilder/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 |
3 | BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run();
--------------------------------------------------------------------------------
/src/main/Benchmarks.QueryBuilder/Services/Query/QueryClass.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.QueryBuilder.Services.Query;
2 |
3 | ///
4 | /// Override of with length.
5 | ///
6 | public sealed class QueryDictionary : Dictionary
7 | {
8 | ///
9 | public QueryDictionary(int size) : base(size)
10 | {
11 | }
12 |
13 | ///
14 | /// Gets overall length of all keys and values by chars.
15 | ///
16 | public int QueryLength { get; private set; }
17 |
18 | ///
19 | /// Override of of dictionary with adding length of key and value.
20 | ///
21 | /// Key.
22 | /// Value.
23 | public new void Add(string key, string value)
24 | {
25 | QueryLength += key.Length + value.Length;
26 |
27 | base.Add(key, value);
28 | }
29 |
30 | ///
31 | /// Override of of dictionary with adding length of key and value.
32 | ///
33 | /// Key.
34 | /// Value.
35 | public new bool TryAdd(string key, string value)
36 | {
37 | QueryLength += key.Length + value.Length;
38 |
39 | return base.TryAdd(key, value);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.QueryBuilder/Services/Query/QueryValueStringBuilder.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) .NET Foundation. All rights reserved.
2 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3 |
4 | using System.Collections;
5 | using System.Text.Encodings.Web;
6 | using Microsoft.AspNetCore.Http;
7 |
8 | namespace Benchmarks.QueryBuilder.Services.Query;
9 |
10 | // The IEnumerable interface is required for the collection initialization syntax: new QueryBuilder() { { "key", "value" } };
11 | public sealed class QueryValueStringBuilder : IEnumerable>
12 | {
13 | private readonly IList> _params;
14 |
15 | public QueryValueStringBuilder()
16 | {
17 | _params = new List>();
18 | }
19 |
20 | public QueryValueStringBuilder(IEnumerable> parameters)
21 | {
22 | _params = new List>(parameters);
23 | }
24 |
25 | public IEnumerator> GetEnumerator()
26 | {
27 | return _params.GetEnumerator();
28 | }
29 |
30 | IEnumerator IEnumerable.GetEnumerator()
31 | {
32 | return _params.GetEnumerator();
33 | }
34 |
35 | public void Add(string key, IEnumerable values)
36 | {
37 | foreach (var value in values) _params.Add(new KeyValuePair(key, value));
38 | }
39 |
40 | public void Add(string key, string value)
41 | {
42 | _params.Add(new KeyValuePair(key, value));
43 | }
44 |
45 | public override string ToString()
46 | {
47 | var builder = new ValueStringBuilder();
48 | var first = true;
49 |
50 | for (var i = 0; i < _params.Count; i++)
51 | {
52 | var pair = _params[i];
53 | builder.Append(first ? "?" : "&");
54 | first = false;
55 | builder.Append(UrlEncoder.Default.Encode(pair.Key));
56 | builder.Append("=");
57 | builder.Append(UrlEncoder.Default.Encode(pair.Value));
58 | }
59 |
60 | return builder.ToString();
61 | }
62 |
63 | public QueryString ToQueryString()
64 | {
65 | return new QueryString(ToString());
66 | }
67 |
68 | public override int GetHashCode()
69 | {
70 | return ToQueryString().GetHashCode();
71 | }
72 |
73 | public override bool Equals(object obj)
74 | {
75 | return ToQueryString().Equals(obj);
76 | }
77 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/Benchmarks.Serializers.Binary.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8
6 | enable
7 | enable
8 | Linux
9 | true
10 | true
11 | true
12 |
13 |
14 |
15 |
16 | .dockerignore
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Serializers.cs
28 |
29 |
30 | Serializers.cs
31 |
32 |
33 | Serializers.cs
34 |
35 |
36 | Serializers.cs
37 |
38 |
39 | Serializers.cs
40 |
41 |
42 | Serializers.cs
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/Benchmarks/SerializationBenchmark.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using Benchmarks.Serializers.Models;
3 | using BenchmarkDotNet.Attributes;
4 | using BenchmarkDotNet.Configs;
5 | using BenchmarkDotNet.Order;
6 | using Bogus;
7 |
8 | namespace Benchmarks.Serializers.Binary.Benchmarks;
9 |
10 | [MemoryDiagnoser, CategoriesColumn, AllStatisticsColumn, Orderer(SummaryOrderPolicy.FastestToSlowest),
11 | GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory), ExcludeFromCodeCoverage]
12 | public class SerializationBenchmark
13 | {
14 | ///
15 | /// Collection of testing .
16 | ///
17 | private SimpleModel[] _simpleModels = [];
18 |
19 | ///
20 | /// Size of generation.
21 | /// **NOTE:** Intentionally left public for BenchmarkDotNet Params.
22 | ///
23 | [Params(1, 100, 1000)]
24 | public int CollectionSize { get; set; }
25 |
26 | ///
27 | /// Setting private fields.
28 | ///
29 | [GlobalSetup]
30 | public void Setup()
31 | {
32 | _simpleModels = new Faker()
33 | .RuleFor(model => model.TestBool, faker => faker.Random.Bool())
34 | .RuleFor(model => model.TestInt, faker => faker.Random.Int())
35 | .RuleFor(model => model.TestString, faker => faker.Name.FullName())
36 | .Generate(CollectionSize)
37 | .ToArray();
38 | }
39 |
40 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
41 | public byte[] MessagePack()
42 | {
43 | return Serializers.MessagePackSerializeBytes(_simpleModels);
44 | }
45 |
46 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
47 | public byte[] MsgPackLight()
48 | {
49 | return Serializers.MsgPackLightSerializeBytes(_simpleModels);
50 | }
51 |
52 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
53 | public byte[] MemoryPack()
54 | {
55 | return Serializers.MemoryPackSerializeBytes(_simpleModels);
56 | }
57 |
58 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
59 | public byte[] ZeroFormatter()
60 | {
61 | return Serializers.ZeroFormatterSerializeBytes(_simpleModels);
62 | }
63 |
64 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
65 | public byte[] Protobuf()
66 | {
67 | return Serializers.ProtobufSerializeBytes(_simpleModels);
68 | }
69 |
70 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
71 | public byte[] FlatBuffers()
72 | {
73 | return Serializers.FlatBufferSerializeBytes(_simpleModels);
74 | }
75 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
2 | USER $APP_UID
3 | WORKDIR /app
4 |
5 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 | ARG BUILD_CONFIGURATION=Release
7 | WORKDIR /src
8 | COPY ["src/main/Benchmark.Serializers.Binary/Benchmark.Serializers.Binary.csproj", "src/main/Benchmark.Serializers.Binary/"]
9 | RUN dotnet restore "src/main/Benchmark.Serializers.Binary/Benchmark.Serializers.Binary.csproj"
10 | COPY . .
11 | WORKDIR "/src/src/main/Benchmark.Serializers.Binary"
12 | RUN dotnet build "Benchmark.Serializers.Binary.csproj" -c $BUILD_CONFIGURATION -o /app/build
13 |
14 | FROM build AS publish
15 | ARG BUILD_CONFIGURATION=Release
16 | RUN dotnet publish "Benchmark.Serializers.Binary.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
17 |
18 | FROM base AS final
19 | WORKDIR /app
20 | COPY --from=publish /app/publish .
21 | ENTRYPOINT ["dotnet", "Benchmark.Serializers.Binary.dll"]
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/MsgPackLightConverters/SimpleModelConverter.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers.Models;
2 | using FastSerialization;
3 | using ProGaudi.MsgPack.Light;
4 |
5 | namespace Benchmarks.Serializers.Binary.MsgPackLightConverters;
6 |
7 | sealed internal class SimpleModelConverter : IMsgPackConverter
8 | {
9 | private IMsgPackConverter _stringConverter;
10 | private IMsgPackConverter _intConverter;
11 | private IMsgPackConverter _boolConverter;
12 | private MsgPackContext _context;
13 |
14 | public void Write(SimpleModel value, IMsgPackWriter writer)
15 | {
16 | if (value == null)
17 | {
18 | _context.NullConverter.Write(null, writer);
19 | return;
20 | }
21 |
22 | writer.WriteMapHeader(3);
23 |
24 | _stringConverter.Write(nameof(value.TestInt), writer);
25 | _intConverter.Write(value.TestInt, writer);
26 |
27 | _stringConverter.Write(nameof(value.TestString), writer);
28 | _stringConverter.Write(value.TestString, writer);
29 |
30 | _stringConverter.Write(nameof(value.TestBool), writer);
31 | _boolConverter.Write(value.TestBool, writer);
32 | }
33 |
34 | public SimpleModel Read(IMsgPackReader reader)
35 | {
36 | var length = reader.ReadMapLength();
37 | if (length == null)
38 | {
39 | return null!;
40 | }
41 |
42 | if (length != 3)
43 | {
44 | throw new SerializationException("Bad format");
45 | }
46 |
47 | var result = new SimpleModel();
48 | for (var i = 0; i < length.Value; i++)
49 | {
50 | var propertyName = _stringConverter.Read(reader);
51 |
52 | switch (propertyName)
53 | {
54 | case nameof(result.TestInt):
55 | result.TestInt = _intConverter.Read(reader);
56 | break;
57 | case nameof(result.TestString):
58 | result.TestString = _stringConverter.Read(reader);
59 | break;
60 | case nameof(result.TestBool):
61 | result.TestBool = _boolConverter.Read(reader);
62 | break;
63 | default:
64 | throw new SerializationException("Bad format");
65 | }
66 | }
67 |
68 | return result;
69 | }
70 |
71 | public void Initialize(MsgPackContext context)
72 | {
73 | _stringConverter = context.GetConverter();
74 | _intConverter = context.GetConverter();
75 | _boolConverter = context.GetConverter();
76 | _context = context;
77 | }
78 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 |
3 | BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run();
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/SerializationBenchmark.FlatBuffer.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers.Models;
2 | using Google.FlatBuffers;
3 |
4 | namespace Benchmarks.Serializers.Binary;
5 |
6 | public static partial class Serializers
7 | {
8 | ///
9 | /// Serializes with .
10 | ///
11 | ///
12 | ///
13 | ///
14 | public static SimpleFlatBufferModels FlatBufferDeserializeBytes(byte[] bytes)
15 | {
16 | var buf = new ByteBuffer(bytes);
17 |
18 | return SimpleFlatBufferModels.GetRootAsSimpleFlatBufferModels(buf);
19 | }
20 |
21 | ///
22 | /// Serializes with .
23 | ///
24 | ///
25 | ///
26 | ///
27 | public static byte[] FlatBufferSerializeBytes(Span simpleModels)
28 | {
29 | var builder = new FlatBufferBuilder(1024);
30 | SimpleFlatBufferModels.StartModelsVector(builder, simpleModels.Length);
31 |
32 | for (var i = 0; i < simpleModels.Length; i++)
33 | {
34 | SimpleFlatBufferModel.CreateSimpleFlatBufferModel(
35 | builder,
36 | simpleModels[i].TestInt,
37 | builder.CreateString(simpleModels[i].TestString),
38 | simpleModels[i].TestBool);
39 | }
40 |
41 | var models = builder.EndVector();
42 |
43 | SimpleFlatBufferModels.StartSimpleFlatBufferModels(builder);
44 | SimpleFlatBufferModels.AddModels(builder, models);
45 |
46 | var simpleFlatBufferModel = SimpleFlatBufferModels.EndSimpleFlatBufferModels(builder);
47 |
48 | builder.Finish(simpleFlatBufferModel.Value);
49 |
50 | return builder.SizedByteArray();
51 | }
52 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/SerializationBenchmark.MemoryPack.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Serializers.Binary;
2 |
3 | public static partial class Serializers
4 | {
5 | ///
6 | /// Serializes with .
7 | ///
8 | ///
9 | ///
10 | ///
11 | public static ICollection MemoryPackDeserializeBytes(byte[] bytes)
12 | {
13 | return MemoryPack.MemoryPackSerializer.Deserialize>(bytes)!;
14 | }
15 | ///
16 | /// Serializes with .
17 | ///
18 | ///
19 | ///
20 | ///
21 | public static byte[] MemoryPackSerializeBytes(T[] simpleModels)
22 | {
23 | return MemoryPack.MemoryPackSerializer.Serialize(simpleModels);
24 | }
25 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/SerializationBenchmark.MessagePack.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Serializers.Binary;
2 |
3 | public static partial class Serializers
4 | {
5 | ///
6 | /// Serializes with .
7 | ///
8 | ///
9 | ///
10 | ///
11 | public static ICollection MessagePackDeserializeBytes(byte[] bytes)
12 | {
13 | return MessagePack.MessagePackSerializer.Deserialize>(bytes);
14 | }
15 | ///
16 | /// Serializes with .
17 | ///
18 | ///
19 | ///
20 | ///
21 | public static byte[] MessagePackSerializeBytes(T[] simpleModels)
22 | {
23 | return MessagePack.MessagePackSerializer.Serialize(simpleModels);
24 | }
25 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/SerializationBenchmark.Protobuf.cs:
--------------------------------------------------------------------------------
1 | using System.Buffers;
2 |
3 | namespace Benchmarks.Serializers.Binary;
4 |
5 | public static partial class Serializers
6 | {
7 | ///
8 | /// Serializes with .
9 | ///
10 | ///
11 | ///
12 | ///
13 | public static ICollection ProtobufDeserializeBytes(ReadOnlySpan bytes)
14 | {
15 | return ProtoBuf.Serializer.Deserialize>(bytes);
16 | }
17 | ///
18 | /// Serializes with .
19 | ///
20 | ///
21 | ///
22 | ///
23 | public static byte[] ProtobufSerializeBytes(T[] simpleModels)
24 | {
25 | var writer = new ArrayBufferWriter();
26 |
27 | ProtoBuf.Serializer.Serialize(writer, simpleModels);
28 |
29 | return writer.WrittenSpan.ToArray();
30 | }
31 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/SerializationBenchmark.ZeroFormatter.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Serializers.Binary;
2 |
3 | public static partial class Serializers
4 | {
5 | ///
6 | /// Serializes with .
7 | ///
8 | ///
9 | ///
10 | ///
11 | public static ICollection ZeroFormatterDeserializeBytes(byte[] bytes)
12 | {
13 | return ZeroFormatter.ZeroFormatterSerializer.Deserialize>(bytes);
14 | }
15 | ///
16 | /// Serializes with .
17 | ///
18 | ///
19 | ///
20 | ///
21 | public static byte[] ZeroFormatterSerializeBytes(T[] simpleModels)
22 | {
23 | return ZeroFormatter.ZeroFormatterSerializer.Serialize(simpleModels);
24 | }
25 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/Serializers.MsgPackLight.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers.Models;
2 | using ProGaudi.MsgPack.Light;
3 |
4 | namespace Benchmarks.Serializers.Binary;
5 |
6 | public static partial class Serializers
7 | {
8 | ///
9 | /// Serializes with .
10 | ///
11 | ///
12 | ///
13 | ///
14 | public static ICollection MsgPackLightDeserializeBytes(byte[] bytes)
15 | {
16 | return MsgPackSerializer.Deserialize>(bytes, MsgPackContext);
17 | }
18 | ///
19 | /// Serializes with .
20 | ///
21 | ///
22 | ///
23 | ///
24 | public static byte[] MsgPackLightSerializeBytes(SimpleModel[] simpleModels)
25 | {
26 | return MsgPackSerializer.Serialize(simpleModels, MsgPackContext);
27 | }
28 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Binary/Serializers.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers.Binary.MsgPackLightConverters;
2 | using ProGaudi.MsgPack.Light;
3 |
4 | namespace Benchmarks.Serializers.Binary;
5 |
6 | public static partial class Serializers
7 | {
8 | private readonly static MsgPackContext MsgPackContext = new();
9 |
10 | static Serializers()
11 | {
12 | MsgPackContext.RegisterConverter(new SimpleModelsConverter());
13 | MsgPackContext.RegisterConverter(new SimpleModelConverter());
14 | }
15 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/DeserializationBenchmark.Jil.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using Benchmarks.Serializers.Models;
3 | using BenchmarkDotNet.Attributes;
4 |
5 | namespace Benchmarks.Serializers.Json.Benchmarks;
6 |
7 | public partial class DeserializationBenchmark
8 | {
9 | [BenchmarkCategory(Group.DeserializationString), Benchmark]
10 | public ICollection JilString()
11 | {
12 | return Serializers.JilDeserialize(_testString);
13 | }
14 |
15 | [BenchmarkCategory(Group.DeserializationByte), Benchmark]
16 | public ICollection JilBytes()
17 | {
18 | return Serializers.JilDeserializeBytes(_testBytes);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/DeserializationBenchmark.JsonSrcGen.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using BenchmarkDotNet.Attributes;
3 | using Benchmarks.Serializers.Json.Models;
4 |
5 | namespace Benchmarks.Serializers.Json.Benchmarks;
6 |
7 | public partial class DeserializationBenchmark
8 | {
9 | [BenchmarkCategory(Group.DeserializationString), Benchmark]
10 | public SimpleSrcGenModel?[]? JsonSrcGenString()
11 | {
12 | return Serializers.JsonSrcGenDeserializeSimpleString(_testString);
13 | }
14 |
15 | [BenchmarkCategory(Group.DeserializationByte), Benchmark]
16 | public SimpleSrcGenModel?[]? JsonSrcGenByte()
17 | {
18 | return Serializers.JsonSrcGenDeserializeSimpleByte(_testBytes);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/DeserializationBenchmark.NetJson.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using Benchmarks.Serializers.Models;
3 | using BenchmarkDotNet.Attributes;
4 |
5 | namespace Benchmarks.Serializers.Json.Benchmarks;
6 |
7 | public partial class DeserializationBenchmark
8 | {
9 | [BenchmarkCategory(Group.DeserializationString), Benchmark]
10 | public ICollection NetJsonString()
11 | {
12 | return Serializers.NetJsonString(_testString);
13 | }
14 |
15 | [BenchmarkCategory(Group.DeserializationByte), Benchmark]
16 | public ICollection NetJsonByte()
17 | {
18 | return Serializers.NetJsonByte(_testBytes);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/DeserializationBenchmark.Newtonsoft.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using Benchmarks.Serializers.Models;
3 | using BenchmarkDotNet.Attributes;
4 |
5 | namespace Benchmarks.Serializers.Json.Benchmarks;
6 |
7 | public partial class DeserializationBenchmark
8 | {
9 | [BenchmarkCategory(Group.DeserializationString), Benchmark]
10 | public ICollection? NewtonsoftString()
11 | {
12 | return Serializers.NewtonsoftString(_testString);
13 | }
14 |
15 | [BenchmarkCategory(Group.DeserializationByte), Benchmark]
16 | public ICollection? NewtonsoftBytes()
17 | {
18 | return Serializers.NewtonsoftBytes(_testBytes);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/DeserializationBenchmark.ServiceStack.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using Benchmarks.Serializers.Models;
3 | using BenchmarkDotNet.Attributes;
4 |
5 | namespace Benchmarks.Serializers.Json.Benchmarks;
6 |
7 | public partial class DeserializationBenchmark
8 | {
9 | [BenchmarkCategory(Group.DeserializationString), Benchmark]
10 | public ICollection ServiceStackString()
11 | {
12 | return Serializers.ServiceStackString(_testString);
13 | }
14 |
15 | [BenchmarkCategory(Group.DeserializationByte), Benchmark]
16 | public ICollection ServiceStackByte()
17 | {
18 | return Serializers.ServiceStackByte(_testBytes);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/DeserializationBenchmark.SpanJson.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using Benchmarks.Serializers.Models;
3 | using BenchmarkDotNet.Attributes;
4 |
5 | namespace Benchmarks.Serializers.Json.Benchmarks;
6 |
7 | public partial class DeserializationBenchmark
8 | {
9 | [BenchmarkCategory(Group.DeserializationString), Benchmark]
10 | public ICollection SpanJsonString()
11 | {
12 | return Serializers.SpanJsonString(_testString);
13 | }
14 |
15 | [BenchmarkCategory(Group.DeserializationByte), Benchmark]
16 | public ICollection SpanJsonByte()
17 | {
18 | return Serializers.SpanJsonByte(_testBytes);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/DeserializationBenchmark.SystemTextJson.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using Benchmarks.Serializers.Models;
3 | using BenchmarkDotNet.Attributes;
4 |
5 | namespace Benchmarks.Serializers.Json.Benchmarks;
6 |
7 | public partial class DeserializationBenchmark
8 | {
9 | [BenchmarkCategory(Group.DeserializationString), Benchmark]
10 | public ICollection? SystemTextJsonString()
11 | {
12 | return Serializers.SystemTextJsonString(_testString);
13 | }
14 |
15 | [BenchmarkCategory(Group.DeserializationByte), Benchmark]
16 | public ICollection? SystemTextJsonByte()
17 | {
18 | return Serializers.SystemTextJsonByte(_testBytes);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/DeserializationBenchmark.SystemTextJsonSrcGen.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using Benchmarks.Serializers.Models;
3 | using BenchmarkDotNet.Attributes;
4 |
5 | namespace Benchmarks.Serializers.Json.Benchmarks;
6 |
7 | public partial class DeserializationBenchmark
8 | {
9 | [BenchmarkCategory(Group.DeserializationString), Benchmark]
10 | public ICollection? SystemTextJsonSourceGenString()
11 | {
12 | return Serializers.SystemTextJsonSourceGenSimpleString(_testString);
13 | }
14 |
15 | [BenchmarkCategory(Group.DeserializationByte), Benchmark]
16 | public ICollection? SystemTextJsonSourceGenByte()
17 | {
18 | return Serializers.SystemTextJsonSourceGenSimpleByte(_testBytes);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/DeserializationBenchmark.Utf8Json.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using Benchmarks.Serializers.Models;
3 | using BenchmarkDotNet.Attributes;
4 |
5 | namespace Benchmarks.Serializers.Json.Benchmarks;
6 |
7 | public partial class DeserializationBenchmark
8 | {
9 | [BenchmarkCategory(Group.DeserializationString), Benchmark]
10 | public ICollection Utf8JsonString()
11 | {
12 | return Serializers.Utf8JsonString(_testString);
13 | }
14 |
15 | [BenchmarkCategory(Group.DeserializationByte), Benchmark]
16 | public ICollection Utf8JsonByte()
17 | {
18 | return Serializers.Utf8JsonByte(_testBytes);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/DeserializationBenchmark.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using System.Runtime.InteropServices;
3 | using System.Text;
4 | using Benchmarks.Serializers.Models;
5 | using BenchmarkDotNet.Attributes;
6 | using BenchmarkDotNet.Configs;
7 | using BenchmarkDotNet.Order;
8 | using Bogus;
9 |
10 | namespace Benchmarks.Serializers.Json.Benchmarks;
11 |
12 | [MemoryDiagnoser,
13 | CategoriesColumn,
14 | AllStatisticsColumn,
15 | Orderer(SummaryOrderPolicy.FastestToSlowest),
16 | GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory), ExcludeFromCodeCoverage]
17 | public partial class DeserializationBenchmark
18 | {
19 | ///
20 | /// Static for .
21 | ///
22 | private readonly static Faker Faker = new();
23 |
24 | private byte[] _testBytes = [];
25 |
26 | private string _testString = string.Empty;
27 |
28 | ///
29 | /// Size of generation.
30 | /// **NOTE:** Intentionally left public for BenchmarkDotNet Params.
31 | ///
32 | [Params(1, 100, 1000)]
33 | public int CollectionSize { get; set; }
34 |
35 | ///
36 | /// Setting private fields.
37 | ///
38 | [GlobalSetup]
39 | public void Setup()
40 | {
41 | var models = Faker
42 | .RuleFor(model => model.TestBool, faker => faker.Random.Bool())
43 | .RuleFor(model => model.TestInt, faker => faker.Random.Int())
44 | .RuleFor(model => model.TestString, faker => faker.Name.FullName())
45 | .Generate(CollectionSize);
46 |
47 | var sb = new StringBuilder();
48 | sb.Append('[');
49 |
50 | var span = CollectionsMarshal.AsSpan(models);
51 |
52 | for (var i = 0; i < span.Length - 1; i++)
53 | {
54 | sb.Append(span[i]);
55 | sb.Append(',');
56 | }
57 |
58 | sb.Append(span[^1]);
59 | sb.Append(']');
60 |
61 | _testString = sb.ToString();
62 | _testBytes = Encoding.UTF8.GetBytes(_testString);
63 | }
64 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/SerializationBenchmark.Jil.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using BenchmarkDotNet.Attributes;
3 |
4 | namespace Benchmarks.Serializers.Json.Benchmarks;
5 |
6 | public partial class SerializationBenchmark
7 | {
8 | [BenchmarkCategory(Group.SerializationString), Benchmark]
9 | public string JilString()
10 | {
11 | return Serializers.JilSerialize(_simpleModels);
12 | }
13 |
14 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
15 | public byte[] JilBytes()
16 | {
17 | return Serializers.JilSerializeBytes(_simpleModels);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/SerializationBenchmark.JsonSrcGen.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using BenchmarkDotNet.Attributes;
3 |
4 | namespace Benchmarks.Serializers.Json.Benchmarks;
5 |
6 | public partial class SerializationBenchmark
7 | {
8 | [BenchmarkCategory(Group.SerializationString), Benchmark]
9 | public string JsonSrcGenString()
10 | {
11 | return Serializers.JsonSrcGenSerializeSimpleString(_simpleSrcGenModels);
12 | }
13 |
14 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
15 | public byte[] JsonSrcGenByte()
16 | {
17 | return Serializers.JsonSrcGenSerializeSimpleByte(_simpleSrcGenModels);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/SerializationBenchmark.NetJson.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using BenchmarkDotNet.Attributes;
3 |
4 | namespace Benchmarks.Serializers.Json.Benchmarks;
5 |
6 | public partial class SerializationBenchmark
7 | {
8 | [BenchmarkCategory(Group.SerializationString), Benchmark]
9 | public string NetJsonString()
10 | {
11 | return Serializers.NetJsonString(_simpleModels);
12 | }
13 |
14 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
15 | public byte[] NetJsonByte()
16 | {
17 | return Serializers.NetJsonByte(_simpleModels);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/SerializationBenchmark.Newtonsoft.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using BenchmarkDotNet.Attributes;
3 |
4 | namespace Benchmarks.Serializers.Json.Benchmarks;
5 |
6 | public partial class SerializationBenchmark
7 | {
8 | [BenchmarkCategory(Group.SerializationString), Benchmark]
9 | public string NewtonsoftString()
10 | {
11 | return Serializers.NewtonsoftString(_simpleModels);
12 | }
13 |
14 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
15 | public byte[] NewtonsoftBytes()
16 | {
17 | return Serializers.NewtonsoftBytes(_simpleModels);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/SerializationBenchmark.ServiceStack.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using BenchmarkDotNet.Attributes;
3 |
4 | namespace Benchmarks.Serializers.Json.Benchmarks;
5 |
6 | public partial class SerializationBenchmark
7 | {
8 | [BenchmarkCategory(Group.SerializationString), Benchmark]
9 | public string ServiceStackString()
10 | {
11 | return Serializers.ServiceStackString(_simpleModels);
12 | }
13 |
14 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
15 | public byte[] ServiceStackByte()
16 | {
17 | return Serializers.ServiceStackByte(_simpleModels);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/SerializationBenchmark.SpanJson.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using BenchmarkDotNet.Attributes;
3 |
4 | namespace Benchmarks.Serializers.Json.Benchmarks;
5 |
6 | public partial class SerializationBenchmark
7 | {
8 | [BenchmarkCategory(Group.SerializationString), Benchmark]
9 | public string SpanJsonString()
10 | {
11 | return Serializers.SpanJsonString(_simpleModels);
12 | }
13 |
14 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
15 | public byte[] SpanJsonByte()
16 | {
17 | return Serializers.SpanJsonByte(_simpleModels);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/SerializationBenchmark.SystemTextJson.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using BenchmarkDotNet.Attributes;
3 |
4 | namespace Benchmarks.Serializers.Json.Benchmarks;
5 |
6 | public partial class SerializationBenchmark
7 | {
8 | [BenchmarkCategory(Group.SerializationString), Benchmark]
9 | public string SystemTextJsonString()
10 | {
11 | return Serializers.SystemTextJsonString(_simpleModels);
12 | }
13 |
14 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
15 | public byte[] SystemTextJsonByte()
16 | {
17 | return Serializers.SystemTextJsonByte(_simpleModels);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/SerializationBenchmark.SystemTextJsonSrcGen.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using BenchmarkDotNet.Attributes;
3 |
4 | namespace Benchmarks.Serializers.Json.Benchmarks;
5 |
6 | public partial class SerializationBenchmark
7 | {
8 | [BenchmarkCategory(Group.SerializationString), Benchmark]
9 | public string SystemTextJsonSourceGenString()
10 | {
11 | return Serializers.SystemTextJsonSourceGenString(_simpleModels);
12 | }
13 |
14 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
15 | public byte[] SystemTextJsonSourceGenByte()
16 | {
17 | return Serializers.SystemTextJsonSourceGenByte(_simpleModels);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/SerializationBenchmark.Utf8Json.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using BenchmarkDotNet.Attributes;
3 |
4 | namespace Benchmarks.Serializers.Json.Benchmarks;
5 |
6 | public partial class SerializationBenchmark
7 | {
8 | [BenchmarkCategory(Group.SerializationString), Benchmark]
9 | public string Utf8JsonString()
10 | {
11 | return Serializers.Utf8JsonString(_simpleModels);
12 | }
13 |
14 | [BenchmarkCategory(Group.SerializationByte), Benchmark]
15 | public byte[] Utf8JsonByte()
16 | {
17 | return Serializers.Utf8JsonByte(_simpleModels);
18 | }
19 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Benchmarks/SerializationBenchmark.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using Benchmarks.Serializers.Models;
3 | using BenchmarkDotNet.Attributes;
4 | using BenchmarkDotNet.Configs;
5 | using BenchmarkDotNet.Order;
6 | using Benchmarks.Serializers.Json.Models;
7 | using Bogus;
8 |
9 | namespace Benchmarks.Serializers.Json.Benchmarks;
10 |
11 | [MemoryDiagnoser, CategoriesColumn, AllStatisticsColumn, Orderer(SummaryOrderPolicy.FastestToSlowest),
12 | GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory), ExcludeFromCodeCoverage]
13 | public partial class SerializationBenchmark
14 | {
15 | ///
16 | /// Static for .
17 | ///
18 | private readonly static Faker Faker = new();
19 |
20 | ///
21 | /// Static for .
22 | ///
23 | private readonly static Faker FakerSrcGen = new();
24 |
25 | ///
26 | /// Collection of testing .
27 | ///
28 | private SimpleModel[] _simpleModels = [];
29 |
30 | ///
31 | /// Collection of testing .
32 | ///
33 | private SimpleSrcGenModel[] _simpleSrcGenModels = [];
34 |
35 | ///
36 | /// Size of generation.
37 | /// **NOTE:** Intentionally left public for BenchmarkDotNet Params.
38 | ///
39 | [Params(1, 100, 1000)]
40 | public int CollectionSize { get; set; }
41 |
42 | ///
43 | /// Setting private fields.
44 | ///
45 | [GlobalSetup]
46 | public void Setup()
47 | {
48 | _simpleModels = Faker
49 | .RuleFor(model => model.TestBool, faker => faker.Random.Bool())
50 | .RuleFor(model => model.TestInt, faker => faker.Random.Int())
51 | .RuleFor(model => model.TestString, faker => faker.Name.FullName())
52 | .Generate(CollectionSize)
53 | .ToArray();
54 |
55 | _simpleSrcGenModels = FakerSrcGen
56 | .RuleFor(model => model.TestBool, faker => faker.Random.Bool())
57 | .RuleFor(model => model.TestInt, faker => faker.Random.Int())
58 | .RuleFor(model => model.TestString, faker => faker.Name.FullName())
59 | .Generate(CollectionSize)
60 | .ToArray();
61 | }
62 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
2 | USER $APP_UID
3 | WORKDIR /app
4 |
5 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 | ARG BUILD_CONFIGURATION=Release
7 | WORKDIR /src
8 | COPY ["src/main/Benchmarks.Json/Benchmarks.Json.csproj", "src/main/Benchmarks.Json/"]
9 | RUN dotnet restore "src/main/Benchmarks.Json/Benchmarks.Json.csproj"
10 | COPY . .
11 | WORKDIR "/src/src/main/Benchmarks.Json"
12 | RUN dotnet build "Benchmarks.Json.csproj" -c $BUILD_CONFIGURATION -o /app/build
13 |
14 | FROM build AS publish
15 | ARG BUILD_CONFIGURATION=Release
16 | RUN dotnet publish "Benchmarks.Json.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
17 |
18 | FROM base AS final
19 | WORKDIR /app
20 | COPY --from=publish /app/publish .
21 | ENTRYPOINT ["dotnet", "Benchmarks.Json.dll"]
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Extensions/JsonServiceExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using Jil;
3 | using MessagePack;
4 | using NetJSON;
5 | using Newtonsoft.Json;
6 | using Newtonsoft.Json.Serialization;
7 | using ServiceStack.Text;
8 |
9 | namespace Benchmarks.Serializers.Json.Extensions;
10 |
11 | ///
12 | /// Extensions for Json services.
13 | ///
14 | public static class JsonServiceExtensions
15 | {
16 | ///
17 | /// Default Options for System.Text.Json.
18 | ///
19 | public readonly static JsonSerializerOptions Options = new()
20 | {
21 | PropertyNamingPolicy = JsonNamingPolicy.CamelCase
22 | };
23 |
24 | public readonly static NetJSONSettings NetJsonOptions = new()
25 | {
26 | DateFormat = NetJSONDateFormat.ISO,
27 | TimeZoneFormat = NetJSONTimeZoneFormat.Utc,
28 | UseStringOptimization = true,
29 | CamelCase = true
30 | };
31 |
32 | public readonly static JsonSerializerSettings NewtonsoftOptions = new()
33 | {
34 | ContractResolver = new CamelCasePropertyNamesContractResolver(),
35 | DateFormatHandling = DateFormatHandling.IsoDateFormat
36 | };
37 |
38 | public readonly static Config ServiceStackOptions = new()
39 | {
40 | DateHandler = DateHandler.ISO8601,
41 | AlwaysUseUtc = true,
42 | TextCase = TextCase.CamelCase
43 | };
44 |
45 | public readonly static Options JilOptions =
46 | new(dateFormat: DateTimeFormat.ISO8601,
47 | serializationNameFormat: SerializationNameFormat.CamelCase);
48 |
49 | public readonly static MessagePackSerializerOptions MsgPackOptions
50 | = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray);
51 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Models/SimpleSrcGenModel.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers;
2 | using JsonSrcGen;
3 |
4 | namespace Benchmarks.Serializers.Json.Models;
5 |
6 | ///
7 | /// Simple deserialization model. Used for tests.
8 | ///
9 | [Json]
10 | public class SimpleSrcGenModel
11 | {
12 | ///
13 | /// Gets or sets test string value.
14 | ///
15 | [JsonName(Fields.TestIntField)]
16 | public virtual int TestInt { get; set; }
17 |
18 | ///
19 | /// Gets or sets test string value.
20 | ///
21 | [JsonName(Fields.TestStringField)]
22 | public virtual string TestString { get; set; } = string.Empty;
23 |
24 | ///
25 | /// Gets or sets test string value.
26 | ///
27 | [JsonName(Fields.TestBoolField)]
28 | public virtual bool TestBool { get; set; }
29 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 | using Benchmarks.Serializers.Json.Models;
3 | using JsonSrcGen;
4 |
5 | [assembly: JsonArray(typeof(ComplexSrcGenModel))]
6 | [assembly: JsonArray(typeof(SimpleSrcGenModel))]
7 |
8 | BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run();
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Serializers.Jil.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Benchmarks.Serializers.Json.Extensions;
3 | using Jil;
4 |
5 | namespace Benchmarks.Serializers.Json;
6 |
7 | public static partial class Serializers
8 | {
9 | ///
10 | /// Serializes with .
11 | ///
12 | ///
13 | ///
14 | ///
15 | public static ICollection JilDeserialize(string input)
16 | {
17 | return JSON.Deserialize>(input, JsonServiceExtensions.JilOptions);
18 | }
19 |
20 | ///
21 | /// Serializes with .
22 | ///
23 | ///
24 | ///
25 | ///
26 | public static ICollection JilDeserializeBytes(byte[] bytes)
27 | {
28 | return JSON.Deserialize>(Encoding.UTF8.GetString(bytes), JsonServiceExtensions.JilOptions);
29 | }
30 |
31 | ///
32 | /// Serializes with .
33 | ///
34 | ///
35 | ///
36 | ///
37 | ///
38 | public static string JilSerialize(T simpleModels)
39 | {
40 | return JSON.Serialize(simpleModels, JsonServiceExtensions.JilOptions);
41 | }
42 |
43 | ///
44 | /// Serializes with .
45 | ///
46 | ///
47 | ///
48 | ///
49 | public static byte[] JilSerializeBytes(T simpleModels)
50 | {
51 | using var writer = new StringWriter();
52 |
53 | JSON.Serialize(simpleModels, writer, JsonServiceExtensions.JilOptions);
54 |
55 | return Encoding.UTF8.GetBytes(writer.ToString());
56 | }
57 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Serializers.JsonSrcGen.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers.Json.Models;
2 | using JsonSrcGen;
3 |
4 | namespace Benchmarks.Serializers.Json;
5 |
6 | public partial class Serializers
7 | {
8 | private readonly static JsonConverter JsonConverter = new();
9 |
10 | ///
11 | /// Serializes with to string.
12 | ///
13 | ///
14 | ///
15 | ///
16 | public static SimpleSrcGenModel?[]? JsonSrcGenDeserializeSimpleString(string testString)
17 | {
18 | return JsonConverter.FromJson(new List().ToArray(), testString);
19 | }
20 |
21 | ///
22 | /// Serializes with .
23 | ///
24 | ///
25 | ///
26 | ///
27 | public static SimpleSrcGenModel?[]? JsonSrcGenDeserializeSimpleByte(byte[] testBytes)
28 | {
29 | return JsonConverter.FromJson(new List().ToArray(), testBytes);
30 | }
31 |
32 | ///
33 | /// Serializes with to string.
34 | ///
35 | ///
36 | ///
37 | ///
38 | ///
39 | public static string JsonSrcGenSerializeSimpleString(SimpleSrcGenModel[] simpleSrcGenModels)
40 | {
41 | return JsonConverter.ToJson(simpleSrcGenModels).ToString();
42 | }
43 |
44 | ///
45 | /// Serializes with .
46 | ///
47 | ///
48 | ///
49 | ///
50 | public static byte[] JsonSrcGenSerializeSimpleByte(SimpleSrcGenModel[] simpleSrcGenModels)
51 | {
52 | return JsonConverter.ToJsonUtf8(simpleSrcGenModels).ToArray();
53 | }
54 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Serializers.NetJson.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Benchmarks.Serializers.Json.Extensions;
3 |
4 | namespace Benchmarks.Serializers.Json;
5 |
6 | public partial class Serializers
7 | {
8 | ///
9 | /// Serializes with to string.
10 | ///
11 | ///
12 | ///
13 | ///
14 | public static ICollection NetJsonString(string testString)
15 | {
16 | return NetJSON.NetJSON.Deserialize>(testString, JsonServiceExtensions.NetJsonOptions);
17 | }
18 |
19 | ///
20 | /// Serializes with to string.
21 | ///
22 | ///
23 | ///
24 | ///
25 | public static ICollection NetJsonByte(byte[] testBytes)
26 | {
27 | return NetJSON.NetJSON.Deserialize>(Encoding.UTF8.GetString(testBytes), JsonServiceExtensions.NetJsonOptions);
28 | }
29 |
30 | ///
31 | /// Serializes with to string.
32 | ///
33 | ///
34 | ///
35 | ///
36 | public static string NetJsonString(T[] array)
37 | {
38 | return NetJSON.NetJSON.Serialize(array, JsonServiceExtensions.NetJsonOptions);
39 | }
40 |
41 | ///
42 | /// Serializes with to string.
43 | ///
44 | ///
45 | ///
46 | ///
47 | public static byte[] NetJsonByte(T[] array)
48 | {
49 | using var writer = new StringWriter();
50 |
51 | NetJSON.NetJSON.Serialize(array, writer, JsonServiceExtensions.NetJsonOptions);
52 |
53 | return Encoding.UTF8.GetBytes(writer.ToString());
54 | }
55 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Serializers.Newtonsoft.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Benchmarks.Serializers.Json.Extensions;
3 | using Newtonsoft.Json;
4 |
5 | namespace Benchmarks.Serializers.Json;
6 |
7 | public partial class Serializers
8 | {
9 | ///
10 | /// Serializes with Newtonsoft.Json.
11 | ///
12 | ///
13 | ///
14 | ///
15 | ///
16 | public static ICollection? NewtonsoftString(string testString)
17 | {
18 | return JsonConvert.DeserializeObject>(testString, JsonServiceExtensions.NewtonsoftOptions);
19 | }
20 |
21 | ///
22 | /// Serializes with Newtonsoft.Json.
23 | ///
24 | ///
25 | ///
26 | ///
27 | ///
28 | public static ICollection? NewtonsoftBytes(byte[] testBytes)
29 | {
30 | return JsonConvert.DeserializeObject>(Encoding.UTF8.GetString(testBytes), JsonServiceExtensions.NewtonsoftOptions);
31 | }
32 |
33 | public static string NewtonsoftString(T[] simpleModels)
34 | {
35 | return JsonConvert.SerializeObject(simpleModels, JsonServiceExtensions.NewtonsoftOptions);
36 | }
37 |
38 | public static byte[] NewtonsoftBytes(T[] simpleModels)
39 | {
40 | return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(simpleModels, JsonServiceExtensions.NewtonsoftOptions));
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Serializers.ServiceStack.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Benchmarks.Serializers.Json.Extensions;
3 | using ServiceStack.Text;
4 |
5 | namespace Benchmarks.Serializers.Json;
6 |
7 | public partial class Serializers
8 | {
9 | ///
10 | /// Serializes with to string.
11 | ///
12 | ///
13 | ///
14 | ///
15 | ///
16 | public static ICollection ServiceStackString(string testString)
17 | {
18 | using (JsConfig.With(JsonServiceExtensions.ServiceStackOptions))
19 | {
20 | return JsonSerializer.DeserializeFromString>(testString);
21 | }
22 | }
23 |
24 | ///
25 | /// Serializes with to string.
26 | ///
27 | ///
28 | ///
29 | ///
30 | ///
31 | public static ICollection ServiceStackByte(byte[] testBytes)
32 | {
33 | using (JsConfig.With(JsonServiceExtensions.ServiceStackOptions))
34 | {
35 | return JsonSerializer.DeserializeFromSpan>(Encoding.UTF8.GetString(testBytes));
36 | }
37 | }
38 |
39 | public static string ServiceStackString(T[] simpleModels)
40 | {
41 | using (JsConfig.With(JsonServiceExtensions.ServiceStackOptions))
42 | {
43 | return JsonSerializer.SerializeToString(simpleModels);
44 | }
45 | }
46 |
47 | public static byte[] ServiceStackByte(T[] simpleModels)
48 | {
49 | using var writer = new StringWriter();
50 |
51 | using (JsConfig.With(JsonServiceExtensions.ServiceStackOptions))
52 | {
53 | JsonSerializer.SerializeToWriter(simpleModels, writer);
54 | }
55 |
56 | return Encoding.UTF8.GetBytes(writer.ToString());
57 | }
58 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Serializers.SpanJson.cs:
--------------------------------------------------------------------------------
1 | using SpanJson;
2 |
3 | namespace Benchmarks.Serializers.Json;
4 |
5 | public partial class Serializers
6 | {
7 | ///
8 | /// Serializes with to string.
9 | ///
10 | ///
11 | ///
12 | ///
13 | ///
14 | public static ICollection SpanJsonString(string testString)
15 | {
16 | return JsonSerializer.Generic.Utf16.Deserialize>(testString)!;
17 | }
18 |
19 | ///
20 | /// Serializes with to string.
21 | ///
22 | ///
23 | ///
24 | ///
25 | ///
26 | public static ICollection SpanJsonByte(byte[] testBytes)
27 | {
28 | return JsonSerializer.Generic.Utf8.Deserialize>(testBytes)!;
29 | }
30 |
31 | public static string SpanJsonString(T[] simpleModels)
32 | {
33 | return JsonSerializer.Generic.Utf16.Serialize(simpleModels)!;
34 | }
35 |
36 | public static byte[] SpanJsonByte(T[] simpleModels)
37 | {
38 | return JsonSerializer.Generic.Utf8.Serialize(simpleModels)!;
39 | }
40 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Serializers.SystemTextJson.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using Benchmarks.Serializers.Json.Extensions;
3 |
4 | namespace Benchmarks.Serializers.Json;
5 |
6 | public partial class Serializers
7 | {
8 | ///
9 | /// Serializes with .
10 | ///
11 | ///
12 | /// .
13 | public static ICollection? SystemTextJsonString(string testString)
14 | {
15 | return JsonSerializer.Deserialize>(testString, JsonServiceExtensions.Options);
16 | }
17 |
18 | ///
19 | /// Serializes with .
20 | ///
21 | ///
22 | /// .
23 | public static ICollection? SystemTextJsonByte(byte[] testBytes)
24 | {
25 | return JsonSerializer.Deserialize>(testBytes, JsonServiceExtensions.Options);
26 | }
27 |
28 | public static string SystemTextJsonString(T[] simpleModels)
29 | {
30 | return JsonSerializer.Serialize(simpleModels, JsonServiceExtensions.Options);
31 | }
32 |
33 | public static byte[] SystemTextJsonByte(T[] simpleModels)
34 | {
35 | return JsonSerializer.SerializeToUtf8Bytes(simpleModels, JsonServiceExtensions.Options);
36 | }
37 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Serializers.SystemTextJsonSrcGen.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using Benchmarks.Serializers.Models;
3 | using ModelsJsonContext = Benchmarks.Serializers.ModelsJsonContext;
4 |
5 | namespace Benchmarks.Serializers.Json;
6 |
7 | public partial class Serializers
8 | {
9 | ///
10 | /// Serializes with source gen.
11 | ///
12 | ///
13 | /// .
14 | public static ICollection? SystemTextJsonSourceGenSimpleString(string testString)
15 | {
16 | return JsonSerializer.Deserialize(testString, ModelsJsonContext.Default.ICollectionSimpleModel);
17 | }
18 |
19 | ///
20 | /// Serializes with source gen.
21 | ///
22 | ///
23 | /// .
24 | public static ICollection? SystemTextJsonSourceGenSimpleByte(byte[] testBytes)
25 | {
26 | return JsonSerializer.Deserialize(testBytes, ModelsJsonContext.Default.ICollectionSimpleModel);
27 | }
28 |
29 | ///
30 | /// Serializes with source gen.
31 | ///
32 | ///
33 | /// .
34 | public static string SystemTextJsonSourceGenString(T[] models)
35 | {
36 | return JsonSerializer.Serialize(models, ModelsJsonContext.Default.ICollectionSimpleModel);
37 | }
38 |
39 | ///
40 | /// Serializes with source gen.
41 | ///
42 | ///
43 | /// .
44 | public static byte[] SystemTextJsonSourceGenByte(T[] models)
45 | {
46 | return JsonSerializer.SerializeToUtf8Bytes(models, ModelsJsonContext.Default.ICollectionSimpleModel);
47 | }
48 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Serializers.Utf8Json.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Utf8Json;
3 |
4 | namespace Benchmarks.Serializers.Json;
5 |
6 | public partial class Serializers
7 | {
8 | ///
9 | /// Serializes with .
10 | ///
11 | ///
12 | ///
13 | ///
14 | ///
15 | public static ICollection Utf8JsonString(string testString)
16 | {
17 | return JsonSerializer.Deserialize>(testString);
18 | }
19 |
20 | ///
21 | /// Serializes with Utf8Json.
22 | ///
23 | ///
24 | ///
25 | ///
26 | public static ICollection Utf8JsonByte(byte[] testBytes)
27 | {
28 | return JsonSerializer.Deserialize>(testBytes);
29 | }
30 |
31 | ///
32 | /// Serializes with .
33 | ///
34 | ///
35 | ///
36 | ///
37 | ///
38 | public static string Utf8JsonString(T[] models)
39 | {
40 | return Encoding.UTF8.GetString(JsonSerializer.Serialize(models));
41 | }
42 |
43 | ///
44 | /// Serializes with Utf8Json.
45 | ///
46 | ///
47 | ///
48 | ///
49 | public static byte[] Utf8JsonByte(T[] models)
50 | {
51 | return JsonSerializer.Serialize(models)!;
52 | }
53 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.Json/Serializers.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Serializers.Json;
2 |
3 | public static partial class Serializers;
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Benchmarks.Serializers.OutputFormatters.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8
5 | enable
6 | enable
7 | true
8 | Linux
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | .dockerignore
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Benchmarks.Serializers.OutputFormatters.http:
--------------------------------------------------------------------------------
1 | @Benchmarks.Serializers.OutputFormatters_HostAddress = http://localhost:5022
2 |
3 | GET {{Benchmarks.Serializers.OutputFormatters_HostAddress}}/weatherforecast/
4 | Accept: application/json
5 |
6 | ###
7 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Controllers/JsonController.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers.Models;
2 | using Benchmarks.Serializers.OutputFormatters.Extensions;
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | namespace Benchmarks.Serializers.OutputFormatters.Controllers;
6 |
7 | [ApiController]
8 | public sealed class JsonController : ControllerBase
9 | {
10 | [HttpGet("serialize/simple/100")]
11 | public ICollection JsonSimple()
12 | {
13 | return SimpleModelGenerator.SimpleModels;
14 | }
15 |
16 | [HttpPost("deserialize/simple/100")]
17 | public ActionResult JsonSimple([FromBody] IEnumerable entry) => Ok();
18 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
2 | USER $APP_UID
3 | WORKDIR /app
4 | EXPOSE 8080
5 | EXPOSE 8081
6 |
7 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
8 | ARG BUILD_CONFIGURATION=Release
9 | WORKDIR /src
10 | COPY ["src/main/Benchmarks.Serializers.OutputFormatters/Benchmarks.Serializers.OutputFormatters.csproj", "src/main/Benchmarks.Serializers.OutputFormatters/"]
11 | RUN dotnet restore "src/main/Benchmarks.Serializers.OutputFormatters/Benchmarks.Serializers.OutputFormatters.csproj"
12 | COPY . .
13 | WORKDIR "/src/src/main/Benchmarks.Serializers.OutputFormatters"
14 | RUN dotnet build "Benchmarks.Serializers.OutputFormatters.csproj" -c $BUILD_CONFIGURATION -o /app/build
15 |
16 | FROM build AS publish
17 | ARG BUILD_CONFIGURATION=Release
18 | RUN dotnet publish "Benchmarks.Serializers.OutputFormatters.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
19 |
20 | FROM base AS final
21 | WORKDIR /app
22 | COPY --from=publish /app/publish .
23 | ENTRYPOINT ["dotnet", "Benchmarks.Serializers.OutputFormatters.dll"]
24 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Extensions/SimpleModelGenerator.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers.Models;
2 | using Bogus;
3 |
4 | namespace Benchmarks.Serializers.OutputFormatters.Extensions;
5 |
6 | public static class SimpleModelGenerator
7 | {
8 | public readonly static ICollection SimpleModels = new Faker()
9 | .RuleFor(model => model.TestBool, y=> y.Random.Bool())
10 | .RuleFor(model => model.TestInt, y=> y.Random.Int())
11 | .RuleFor(model => model.TestString, y=> y.Name.FullName())
12 | .Generate(100);
13 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/Jil/JilInputFormatter.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Jil;
3 | using Microsoft.AspNetCore.Mvc.Formatters;
4 |
5 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.Jil;
6 |
7 | public sealed class JilInputFormatter : InputFormatter
8 | {
9 | private readonly Options _jilOptions;
10 |
11 | public JilInputFormatter(Options jilOptions)
12 | {
13 | _jilOptions = jilOptions;
14 | SupportedMediaTypes.Add("application/json");
15 | SupportedMediaTypes.Add("text/json");
16 | SupportedMediaTypes.Add("application/*+json");
17 | }
18 |
19 | public override async Task ReadRequestBodyAsync(InputFormatterContext context)
20 | {
21 | var request = context.HttpContext.Request;
22 | var result = await JSON.DeserializeDynamicAsync(request.BodyReader, Encoding.UTF8, _jilOptions);
23 |
24 | return await InputFormatterResult.SuccessAsync(result);
25 | }
26 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/Jil/JilOutputFormatter.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Jil;
3 | using Microsoft.AspNetCore.Mvc.Formatters;
4 |
5 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.Jil;
6 |
7 | public sealed class JilOutputFormatter : OutputFormatter
8 | {
9 | private readonly Options _jilOptions;
10 |
11 | public JilOutputFormatter(Options jilOptions)
12 | {
13 | _jilOptions = jilOptions;
14 | SupportedMediaTypes.Add("application/json");
15 | SupportedMediaTypes.Add("text/json");
16 | SupportedMediaTypes.Add("application/*+json");
17 | }
18 |
19 | public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
20 | {
21 | if (context.Object is null)
22 | {
23 | var writer = context.HttpContext.Response.BodyWriter;
24 | if (writer is null)
25 | {
26 | context.HttpContext.Response.Body.WriteByte((byte)'{');
27 | context.HttpContext.Response.Body.WriteByte((byte)'}');
28 |
29 | return Task.CompletedTask;
30 | }
31 |
32 | var span = writer.GetSpan(2);
33 | span[0] = (byte)'{';
34 | span[1] = (byte)'}';
35 |
36 | writer.Advance(2);
37 |
38 | return writer.FlushAsync().AsTask();
39 | }
40 | else
41 | {
42 | var writer = context.HttpContext.Response.BodyWriter;
43 |
44 | return JSON.SerializeAsync(context.Object, writer: writer, Encoding.UTF8, _jilOptions).AsTask();
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/Jil/MvcOptionsExtensions.cs:
--------------------------------------------------------------------------------
1 | using Jil;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.Jil;
5 |
6 | public static class MvcOptionsExtension
7 | {
8 | private readonly static Options JilOptions = new(dateFormat: DateTimeFormat.ISO8601, serializationNameFormat: SerializationNameFormat.CamelCase);
9 |
10 | public static IMvcBuilder AddJilFormatter(this IMvcBuilder mvcBuilder)
11 | {
12 | // // Workaround of Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
13 | // mvcBuilder.Services.Configure(options =>
14 | // {
15 | // options.AllowSynchronousIO = true;
16 | // });
17 |
18 | Configure(mvcBuilder.Services);
19 |
20 | return mvcBuilder;
21 | }
22 |
23 | private static void Configure(IServiceCollection serviceCollection) => serviceCollection.Configure((Action) (options =>
24 | {
25 | options.OutputFormatters.Clear();
26 | options.InputFormatters.Clear();
27 |
28 | options.InputFormatters.Add(new JilInputFormatter(JilOptions));
29 | options.OutputFormatters.Add(new JilOutputFormatter(JilOptions));
30 | }));
31 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/MemoryPack/MvcOptionsExtensions.cs:
--------------------------------------------------------------------------------
1 | using MemoryPack.AspNetCoreMvcFormatter;
2 | using MessagePack;
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.MemoryPack;
6 |
7 | public static class MvcOptionsExtension
8 | {
9 | private readonly static MessagePackSerializerOptions MsgPackOptions
10 | = MessagePackSerializerOptions.Standard;
11 |
12 | public static IMvcBuilder AddMemoryPackFormatter(this IMvcBuilder mvcBuilder)
13 | {
14 | Configure(mvcBuilder.Services);
15 |
16 | return mvcBuilder;
17 | }
18 |
19 | private static void Configure(IServiceCollection serviceCollection) => serviceCollection.Configure((Action) (config =>
20 | {
21 | config.OutputFormatters.Clear();
22 | config.InputFormatters.Clear();
23 | config.OutputFormatters.Add(new MemoryPackOutputFormatter());
24 | config.InputFormatters.Add(new MemoryPackInputFormatter());
25 | }));
26 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/MessagePack/MvcOptionsExtensions.cs:
--------------------------------------------------------------------------------
1 | using MessagePack;
2 | using MessagePack.AspNetCoreMvcFormatter;
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.MessagePack;
6 |
7 | public static class MvcOptionsExtension
8 | {
9 | private readonly static MessagePackSerializerOptions MsgPackOptions
10 | = MessagePackSerializerOptions.Standard;
11 |
12 | public static IMvcBuilder AddMsgPackFormatter(this IMvcBuilder mvcBuilder)
13 | {
14 | Configure(mvcBuilder.Services);
15 |
16 | return mvcBuilder;
17 | }
18 |
19 | private static void Configure(IServiceCollection serviceCollection) => serviceCollection.Configure((Action) (config =>
20 | {
21 | config.OutputFormatters.Clear();
22 | config.InputFormatters.Clear();
23 | config.OutputFormatters.Add(new MessagePackOutputFormatter(MsgPackOptions));
24 | config.InputFormatters.Add(new MessagePackInputFormatter(MsgPackOptions));
25 | }));
26 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/Newtonsoft/MvcOptionsExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.Newtonsoft;
4 |
5 | public static class MvcOptionsExtension
6 | {
7 | public static IMvcBuilder AddNewtonsoftFormatter(this IMvcBuilder builder)
8 | {
9 | builder.Services.Configure((Action) (config =>
10 | {
11 | config.OutputFormatters.Clear();
12 | config.InputFormatters.Clear();
13 | }));
14 |
15 | return builder.AddNewtonsoftJson();
16 | }
17 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/Protobuf/MvcOptionsExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.Protobuf;
4 |
5 | public static class MvcOptionsExtension
6 | {
7 | public static IMvcBuilder AddProtobufFormatter(this IMvcBuilder builder)
8 | {
9 | builder.Services.Configure((Action) (config =>
10 | {
11 | config.OutputFormatters.Clear();
12 | config.InputFormatters.Clear();
13 | }));
14 |
15 | return builder.AddProtoBufNet();
16 | }
17 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/SpanJson/MvcOptionsExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using SpanJson;
3 | using SpanJson.AspNetCore.Formatter;
4 |
5 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.SpanJson;
6 |
7 | public static class MvcOptionsExtension
8 | {
9 | public static IMvcBuilder AddSpanJsonFormatter(this IMvcBuilder mvcBuilder)
10 | {
11 | return mvcBuilder.AddSpanJsonCustom>();
12 | }
13 |
14 | public static IMvcBuilder AddSpanJsonFormatterV2(this IMvcBuilder mvcBuilder)
15 | {
16 | Configure>(mvcBuilder.Services);
17 |
18 | return mvcBuilder;
19 | }
20 |
21 | private static void Configure(IServiceCollection serviceCollection) where TResolver : IJsonFormatterResolver, new()
22 | => serviceCollection.Configure((Action) (config =>
23 | {
24 | config.OutputFormatters.Clear();
25 | config.InputFormatters.Clear();
26 | config.InputFormatters.Add(new SpanJsonInputFormatter());
27 | config.OutputFormatters.Add(new SpanJsonOutputFormatter());
28 | }));
29 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/SpanJson/SpanJsonFormatter.cs:
--------------------------------------------------------------------------------
1 | using SpanJson.Resolvers;
2 |
3 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.SpanJson;
4 |
5 | sealed internal class SpanJsonFormatter() : ResolverBase>(new SpanJsonOptions
6 | {
7 | NamingConvention = NamingConventions.CamelCase,
8 | NullOption = NullOptions.ExcludeNulls,
9 | EnumOption = EnumOptions.String
10 | })
11 | where TSymbol : struct;
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/SpanJson/SpanJsonInputFormatter.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Microsoft.AspNetCore.Mvc.Formatters;
3 | using SpanJson;
4 |
5 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.SpanJson;
6 |
7 | public sealed class SpanJsonInputFormatter : TextInputFormatter where TResolver : IJsonFormatterResolver, new()
8 | {
9 | public SpanJsonInputFormatter()
10 | {
11 | SupportedMediaTypes.Add("application/json");
12 | SupportedMediaTypes.Add("text/json");
13 | SupportedMediaTypes.Add("application/*+json");
14 | SupportedEncodings.Add(UTF8EncodingWithoutBOM);
15 | }
16 |
17 | public override async Task ReadRequestBodyAsync(
18 | InputFormatterContext context,
19 | Encoding encoding)
20 | {
21 | try
22 | {
23 | var model = await JsonSerializer.NonGeneric.Utf8.DeserializeAsync(context.HttpContext.Request.Body, context.ModelType);
24 |
25 | return model is not null || context.TreatEmptyInputAsDefaultValue
26 | ? await InputFormatterResult.SuccessAsync(model)
27 | : await InputFormatterResult.NoValueAsync();
28 | }
29 | catch (Exception ex)
30 | {
31 | context.ModelState.AddModelError("JSON", ex.Message);
32 |
33 | return await InputFormatterResult.FailureAsync();
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/SpanJson/SpanJsonOutputFormatter.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Microsoft.AspNetCore.Mvc.Formatters;
3 | using SpanJson;
4 |
5 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.SpanJson;
6 |
7 | public sealed class SpanJsonOutputFormatter : TextOutputFormatter where TResolver : IJsonFormatterResolver, new()
8 | {
9 | public SpanJsonOutputFormatter()
10 | {
11 | SupportedMediaTypes.Add("application/json");
12 | SupportedMediaTypes.Add("text/json");
13 | SupportedMediaTypes.Add("application/*+json");
14 | SupportedEncodings.Add(Encoding.UTF8);
15 | }
16 |
17 | public override async Task WriteResponseBodyAsync(
18 | OutputFormatterWriteContext context,
19 | Encoding encoding)
20 | {
21 | if (context.Object is null)
22 | {
23 | return;
24 | }
25 |
26 | var valueTask = JsonSerializer.NonGeneric.Utf8.SerializeAsync(context.Object, context.HttpContext.Response.Body);
27 |
28 | if (valueTask.IsCompletedSuccessfully)
29 | {
30 | return;
31 | }
32 |
33 | await valueTask;
34 | }
35 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/SystemTextJson/MvcOptionsExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using Benchmarks.Serializers;
3 |
4 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.SystemTextJson;
5 |
6 | public static class MvcOptionsExtension
7 | {
8 | private readonly static JsonSerializerOptions Options = new()
9 | {
10 | PropertyNamingPolicy = JsonNamingPolicy.CamelCase
11 | };
12 |
13 | public static IMvcBuilder AddSystemTextJsonSrcGenFormatter(this IMvcBuilder builder)
14 | {
15 | builder.AddJsonOptions(options =>
16 | {
17 | options.JsonSerializerOptions.AddContext();
18 | });
19 |
20 | return builder;
21 | }
22 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Formatters/Utf8Json/MvcOptionsExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 | using Utf8Json.AspNetCoreMvcFormatter;
3 | using Utf8Json.Resolvers;
4 |
5 | namespace Benchmarks.Serializers.OutputFormatters.Formatters.Utf8Json;
6 |
7 | public static class MvcOptionsExtension
8 | {
9 | public static IMvcBuilder AddUtf8JsonFormatter(this IMvcBuilder mvcBuilder)
10 | {
11 | Configure(mvcBuilder.Services);
12 |
13 | return mvcBuilder;
14 | }
15 |
16 | private static void Configure(IServiceCollection serviceCollection) => serviceCollection.Configure((Action) (config =>
17 | {
18 | config.OutputFormatters.Clear();
19 | config.InputFormatters.Clear();
20 | config.OutputFormatters.Add(new JsonOutputFormatter(StandardResolver.CamelCase));
21 | config.InputFormatters.Add(new JsonInputFormatter());
22 | }));
23 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/Program.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers.Models;
2 | using Benchmarks.Serializers.OutputFormatters.Extensions;
3 | using Benchmarks.Serializers.OutputFormatters.Formatters.Jil;
4 | using Benchmarks.Serializers.OutputFormatters.Formatters.MemoryPack;
5 | using Benchmarks.Serializers.OutputFormatters.Formatters.MessagePack;
6 | using Benchmarks.Serializers.OutputFormatters.Formatters.Protobuf;
7 | using Benchmarks.Serializers.OutputFormatters.Formatters.SpanJson;
8 | using Benchmarks.Serializers.OutputFormatters.Formatters.SystemTextJson;
9 | using Benchmarks.Serializers.OutputFormatters.Formatters.Utf8Json;
10 | using Microsoft.AspNetCore.Mvc;
11 |
12 | namespace Benchmarks.Serializers.OutputFormatters;
13 |
14 | public static class Program
15 | {
16 | public static void Main(string[] args)
17 | {
18 | var builder = WebApplication.CreateBuilder(args);
19 |
20 | if (builder.Environment.IsProduction())
21 | {
22 | builder.Logging.ClearProviders();
23 | }
24 |
25 | builder.Services
26 | .AddControllers()
27 | // .AddJilFormatter();
28 | // .AddSystemTextJsonSrcGenFormatter();
29 | // .AddUtf8JsonFormatter();
30 | // .AddSpanJsonFormatter();
31 | // .AddSpanJsonFormatterV2();
32 | // .AddNewtonsoftJson();
33 | // .AddJilFormatter();
34 | .AddProtobufFormatter();
35 | // .AddMemoryPackFormatter();
36 | // .AddMsgPackFormatter();
37 |
38 | builder.Services.AddEndpointsApiExplorer();
39 | builder.Services.AddSwaggerGen();
40 |
41 | var app = builder.Build();
42 |
43 | if (app.Environment.IsDevelopment())
44 | {
45 | app.UseSwagger();
46 | app.UseSwaggerUI();
47 | }
48 |
49 | app.MapControllers();
50 |
51 | app.Run();
52 | }
53 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "AllowedHosts": "*"
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers.OutputFormatters/locustfile.py:
--------------------------------------------------------------------------------
1 | from locust import HttpUser, between, task, tag
2 |
3 | class Tests(HttpUser):
4 | wait_time = between(0.5, 2.5)
5 |
6 | def on_start(self):
7 | self.client.verify = False
8 |
9 | @task
10 | def simpleSerialize(self):
11 | self.client.get(
12 | url="/serialize/simple/100",
13 | verify=False,
14 | headers={"accept": "application/protobuf", "Content-Type": "application/protobuf"})
15 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers/Benchmarks.Serializers.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8
5 | enable
6 | enable
7 | true
8 | true
9 | true
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers/Fields.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Serializers;
2 |
3 | public static class Fields
4 | {
5 | public const string TestIntField = "testInt";
6 |
7 | public const string TestStringField = "testString";
8 |
9 | public const string TestBoolField = "testBool";
10 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers/Group.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.Serializers;
2 |
3 | public static class Group
4 | {
5 | public const string SerializationString = "Serialization. String";
6 |
7 | public const string SerializationByte = "Serialization. Byte Array";
8 |
9 | public const string DeserializationString = "Deserialization. String";
10 |
11 | public const string DeserializationByte = "Deserialization. Byte Array";
12 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers/Models/SimpleModel.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.Serialization;
2 | using System.Text.Json.Serialization;
3 | using MemoryPack;
4 | using MessagePack;
5 | using NetJSON;
6 | using Newtonsoft.Json;
7 | using ProGaudi.MsgPack.Light;
8 | using ProtoBuf;
9 | using ZeroFormatter;
10 |
11 | namespace Benchmarks.Serializers.Models;
12 |
13 | ///
14 | /// Simple deserialization model. Used for tests.
15 | ///
16 | [ProtoContract, ZeroFormattable, MessagePackObject(true), MemoryPackable]
17 | public partial class SimpleModel
18 | {
19 | ///
20 | /// Gets or sets test string value.
21 | ///
22 | [MsgPackMapElement(nameof(TestInt))]
23 | [MsgPackArrayElement(0)]
24 | [Index(1), ProtoMember(1), DataMember(Name = Fields.TestIntField), JsonPropertyName(Fields.TestIntField), JsonProperty(Fields.TestIntField),
25 | NetJSONProperty(Fields.TestIntField)]
26 | public virtual int TestInt { get; set; }
27 |
28 | ///
29 | /// Gets or sets test string value.
30 | ///
31 | [MsgPackMapElement(nameof(TestString))]
32 | [MsgPackArrayElement(1)]
33 | [Index(2), ProtoMember(2), DataMember(Name = Fields.TestStringField), JsonPropertyName(Fields.TestStringField), JsonProperty(Fields.TestStringField),
34 | NetJSONProperty(Fields.TestStringField)]
35 | public virtual string TestString { get; set; } = string.Empty;
36 |
37 | ///
38 | /// Gets or sets test string value.
39 | ///
40 | [MsgPackMapElement(nameof(TestBool))]
41 | [MsgPackArrayElement(2)]
42 | [Index(3), ProtoMember(3), DataMember(Name = Fields.TestBoolField), JsonPropertyName(Fields.TestBoolField), JsonProperty(Fields.TestBoolField),
43 | NetJSONProperty(Fields.TestBoolField)]
44 | public virtual bool TestBool { get; set; }
45 |
46 | public override string ToString()
47 | {
48 | var boolValue = TestBool ? "true" : "false";
49 |
50 | return "{" +
51 | $"\"{Fields.TestIntField}\":{TestInt}," +
52 | $"\"{Fields.TestStringField}\":\"{TestString}\"," +
53 | $"\"{Fields.TestBoolField}\":{boolValue}" +
54 | "}";
55 | }
56 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers/ModelsJsonContext.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 | using Benchmarks.Serializers.Models;
3 |
4 | namespace Benchmarks.Serializers;
5 |
6 | ///
7 | [JsonSerializable(typeof(ICollection)), JsonSerializable(typeof(ICollection)), JsonSourceGenerationOptions(
8 | GenerationMode = JsonSourceGenerationMode.Default,
9 | PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
10 | public sealed partial class ModelsJsonContext : JsonSerializerContext;
--------------------------------------------------------------------------------
/src/main/Benchmarks.Serializers/SimpleFlatBufferModel.fbs:
--------------------------------------------------------------------------------
1 | namespace Benchmark.Serializers.Models;
2 |
3 | table SimpleFlatBufferModel {
4 | test_int:int;
5 | test_string:string;
6 | test_bool:bool;
7 | }
8 |
9 | table SimpleFlatBufferModels {
10 | models:[SimpleFlatBufferModel];
11 | }
12 |
13 | root_type SimpleFlatBufferModels;
--------------------------------------------------------------------------------
/src/main/Benchmarks.SortArrayByArray/Benchmarks.SortArrayByArray.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8
6 | enable
7 | enable
8 | Linux
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.SortArrayByArray/Extensions/EnumerableExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.SortArrayByArray.Extensions;
2 |
3 | public static class EnumerableExtensions
4 | {
5 |
6 | public static IList Shuffle(this IEnumerable sequence)
7 | {
8 | return sequence.Shuffle(Random.Shared);
9 | }
10 |
11 | private static IList Shuffle(this IEnumerable sequence, Random randomNumberGenerator)
12 | {
13 | if (sequence == null)
14 | {
15 | throw new ArgumentNullException(nameof(sequence));
16 | }
17 |
18 | if (randomNumberGenerator == null)
19 | {
20 | throw new ArgumentNullException(nameof(randomNumberGenerator));
21 | }
22 |
23 | var values = sequence.ToList();
24 | var currentlySelecting = values.Count;
25 | while (currentlySelecting > 1)
26 | {
27 | var selectedElement = randomNumberGenerator.Next(currentlySelecting);
28 | --currentlySelecting;
29 | if (currentlySelecting != selectedElement)
30 | {
31 | (values[currentlySelecting], values[selectedElement]) = (values[selectedElement], values[currentlySelecting]);
32 | }
33 | }
34 |
35 | return values;
36 | }
37 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.SortArrayByArray/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 | using Benchmarks.SortArrayByArray;
3 |
4 | BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run();
--------------------------------------------------------------------------------
/src/main/Benchmarks.SortArrayByArray/TestModel.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.SortArrayByArray;
2 |
3 | public sealed class TestModel
4 | {
5 | public required string Id { get; init; }
6 |
7 | public required int TestNumber { get; init; }
8 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.SortArrayByArray/readme.md:
--------------------------------------------------------------------------------
1 | | Method | Size | Mean | Error | StdDev | StdErr | Min | Q1 | Median | Q3 | Max | Op/s | Ratio | Gen0 | Allocated | Alloc Ratio |
2 | |---------------------|--------|---------:|---------:|---------:|---------:|---------:|---------:|---------:|---------:|---------:|-------------:|------:|-------:|----------:|------------:|
3 | | 'V2 order' | 10 | 23.04 ns | 0.049 ns | 0.046 ns | 0.012 ns | 22.93 ns | 23.02 ns | 23.06 ns | 23.08 ns | 23.09 ns | 43,399,713.7 | 0.26 | 0.0229 | 144 B | 0.38 |
4 | | 'V1 order Improved' | 10 | 37.91 ns | 0.107 ns | 0.100 ns | 0.026 ns | 37.72 ns | 37.83 ns | 37.92 ns | 37.99 ns | 38.03 ns | 26,379,502.7 | 0.43 | 0.0357 | 224 B | 0.60 |
5 | | 'V1 order' | 10 | 88.42 ns | 0.167 ns | 0.156 ns | 0.040 ns | 88.10 ns | 88.29 ns | 88.48 ns | 88.51 ns | 88.62 ns | 11,310,145.7 | 1.00 | 0.0598 | 376 B | 1.00 |
6 | | | | | | | | | | | | | | | | | |
7 | | 'V2 order' | 100000 | 22.96 ns | 0.056 ns | 0.053 ns | 0.014 ns | 22.83 ns | 22.93 ns | 22.97 ns | 23.00 ns | 23.01 ns | 43,561,243.0 | 0.26 | 0.0229 | 144 B | 0.38 |
8 | | 'V1 order Improved' | 100000 | 37.91 ns | 0.048 ns | 0.042 ns | 0.011 ns | 37.84 ns | 37.88 ns | 37.89 ns | 37.93 ns | 37.98 ns | 26,380,337.2 | 0.43 | 0.0357 | 224 B | 0.60 |
9 | | 'V1 order' | 100000 | 88.39 ns | 0.115 ns | 0.108 ns | 0.028 ns | 88.11 ns | 88.37 ns | 88.43 ns | 88.46 ns | 88.52 ns | 11,313,218.9 | 1.00 | 0.0598 | 376 B | 1.00 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Stopwatch/Benchmarks.Stopwatch.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Stopwatch/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 |
3 | namespace Benchmarks.Stopwatch;
4 |
5 | internal static class Program
6 | {
7 | public static void Main(string[] args)
8 | {
9 | BenchmarkRunner.Run(typeof(Program).Assembly);
10 | }
11 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.Stopwatch/README.MD:
--------------------------------------------------------------------------------
1 | ```
2 |
3 | BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.3194)
4 | Unknown processor
5 | .NET SDK 9.0.100
6 | [Host] : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX2
7 | DefaultJob : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX2
8 |
9 |
10 | ```
11 | | Method | Mean | Error | StdDev | StdErr | Min | Q1 | Median | Q3 | Max | Op/s | Ratio | Gen0 | Allocated | Alloc Ratio |
12 | |----------------------------------------------------------------------|---------:|---------:|---------:|---------:|---------:|---------:|---------:|---------:|---------:|-------------:|------:|-------:|----------:|------------:|
13 | | Stopwatch.GetElapsedTime(System.Diagnostics.Stopwatch.GetTimestamp() | 23.61 ns | 0.066 ns | 0.058 ns | 0.016 ns | 23.49 ns | 23.57 ns | 23.61 ns | 23.65 ns | 23.71 ns | 42,356,265.5 | 0.88 | - | - | 0.00 |
14 | | Stopwatch.StartNew().Elapsed | 26.78 ns | 0.113 ns | 0.106 ns | 0.027 ns | 26.52 ns | 26.73 ns | 26.75 ns | 26.86 ns | 26.96 ns | 37,343,337.0 | 1.00 | 0.0032 | 40 B | 1.00 |
15 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.Stopwatch/TimeBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using BenchmarkDotNet.Configs;
4 | using BenchmarkDotNet.Order;
5 |
6 | namespace Benchmarks.Stopwatch;
7 |
8 | [MemoryDiagnoser]
9 | [CategoriesColumn]
10 | [AllStatisticsColumn]
11 | [Orderer(SummaryOrderPolicy.FastestToSlowest)]
12 | [GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByParams)]
13 | [MarkdownExporterAttribute.GitHub]
14 | [CsvMeasurementsExporter]
15 | [ExcludeFromCodeCoverage]
16 | public class TimeBenchmarks
17 | {
18 | [Benchmark(Description = "Stopwatch.StartNew().Elapsed", Baseline = true)]
19 | public TimeSpan Old()
20 | {
21 | return System.Diagnostics.Stopwatch.StartNew().Elapsed;
22 | }
23 |
24 | [Benchmark(Description = "Stopwatch.GetElapsedTime(System.Diagnostics.Stopwatch.GetTimestamp()")]
25 | public TimeSpan New()
26 | {
27 | return System.Diagnostics.Stopwatch.GetElapsedTime(System.Diagnostics.Stopwatch.GetTimestamp());
28 | }
29 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Benchmarks.String.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8
6 | enable
7 | enable
8 | Linux
9 |
10 |
11 |
12 |
13 | .dockerignore
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Benchmarks/Abstractions/BenchmarkBase.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using BenchmarkDotNet.Configs;
4 | using BenchmarkDotNet.Engines;
5 | using BenchmarkDotNet.Order;
6 | using Benchmarks.String.Models;
7 | using Bogus;
8 |
9 | namespace Benchmarks.String.Benchmarks.Abstractions;
10 |
11 | ///
12 | /// Base abstraction for benchmarks.
13 | ///
14 | [MemoryDiagnoser, CategoriesColumn, AllStatisticsColumn, Orderer(SummaryOrderPolicy.FastestToSlowest),
15 | GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByParams), MarkdownExporterAttribute.GitHub, CsvMeasurementsExporter, RPlotExporter, ExcludeFromCodeCoverage]
16 | public class BenchmarkBase
17 | {
18 | ///
19 | /// Benchmark Consumer.
20 | ///
21 | protected readonly Consumer Consumer = new();
22 |
23 | ///
24 | /// Collection of for benchmarks.
25 | ///
26 | protected StringsTestModel TestStringArray = null!;
27 |
28 | ///
29 | /// Gets or sets flag whether stack should be triggered or other collections.
30 | ///
31 | [Params(true, false)]
32 | public bool IsStack { get; set; }
33 |
34 | ///
35 | /// Global setup.
36 | ///
37 | [GlobalSetup]
38 | public void Setup()
39 | {
40 | //stackalloc is used when sum of chars is less than 64. So we do generate random bigger that 64 to eliminate this behaviour.
41 |
42 | var from = IsStack ? 65 : 5;
43 | var to = IsStack ? 100 : 20;
44 |
45 | TestStringArray = new Faker()
46 | .RuleFor(x => x.Values, y => [y.Random.String2(from, to), y.Random.String2(from, to)])
47 | .Generate(1)[0];
48 | }
49 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Benchmarks/Abstractions/BenchmarkCollectionBase.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using BenchmarkDotNet.Configs;
4 | using BenchmarkDotNet.Engines;
5 | using BenchmarkDotNet.Order;
6 | using Benchmarks.String.Models;
7 | using Bogus;
8 |
9 | namespace Benchmarks.String.Benchmarks.Abstractions;
10 |
11 | ///
12 | /// Base abstraction for benchmarks.
13 | ///
14 | [MemoryDiagnoser, CategoriesColumn, AllStatisticsColumn, Orderer(SummaryOrderPolicy.FastestToSlowest),
15 | GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByParams), MarkdownExporterAttribute.GitHub, CsvMeasurementsExporter, ExcludeFromCodeCoverage]
16 | public class BenchmarkCollectionBase
17 | {
18 | ///
19 | /// Benchmark .
20 | ///
21 | protected readonly Consumer Consumer = new();
22 |
23 | ///
24 | /// Collection of for benchmarks.
25 | ///
26 | protected List TestStringArray = null!;
27 |
28 | ///
29 | /// Gets or sets flag whether stack should be triggered or other collections.
30 | ///
31 | [Params(true, false)]
32 | public bool IsStack { get; set; }
33 |
34 | ///
35 | /// Parameter for models count.
36 | /// **NOTE:** Intentionally left public for BenchmarkDotNet Params.
37 | ///
38 | [Params(10, 100, 1000)]
39 | public int Values { get; set; }
40 |
41 | ///
42 | /// Global setup.
43 | ///
44 | [GlobalSetup]
45 | public void Setup()
46 | {
47 | //stackalloc is used when sum of chars is less than 64. So we do generate random bigger that 64 to eliminate this behaviour.
48 | TestStringArray = IsStack
49 | ? new Faker()
50 | .RuleFor(x => x.Values, y => new[] {y.Random.String2(5, 20), y.Random.String2(5, 20)})
51 | .Generate(Values)
52 | : new Faker()
53 | .RuleFor(x => x.Values, y => new[] {y.Random.String2(65, 100), y.Random.String2(40, 100)})
54 | .Generate(Values);
55 | }
56 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Benchmarks/DashStringBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using BenchmarkDotNet.Engines;
4 | using Benchmarks.String.Benchmarks.Abstractions;
5 | using Benchmarks.String.Services;
6 |
7 | namespace Benchmarks.String.Benchmarks;
8 |
9 | ///
10 | /// Benchmarking building link.
11 | ///
12 | [ExcludeFromCodeCoverage]
13 | public class DashStringBenchmarks : BenchmarkCollectionBase
14 | {
15 | ///
16 | /// Dash format with SpanOwner.
17 | ///
18 | [BenchmarkCategory(Group.DashView), Benchmark]
19 | public void DashFormatSpanOwner()
20 | {
21 | TestStringArray
22 | .Select(stringsTestModel => SpanOwnerStringService.ToDashFormat(stringsTestModel.Values))
23 | .Consume(Consumer);
24 | }
25 |
26 | ///
27 | /// Dash format with SpanOwner.
28 | ///
29 | [BenchmarkCategory(Group.DashView), Benchmark]
30 | public void DashFormatRegex()
31 | {
32 | TestStringArray
33 | .Select(stringsTestModel => RegexStringService.ToDashFormat(stringsTestModel.Values))
34 | .Consume(Consumer);
35 | }
36 |
37 | ///
38 | /// Dash format with ArrayPool.
39 | ///
40 | [BenchmarkCategory(Group.DashView), Benchmark]
41 | public void DashFormatArrayPool()
42 | {
43 | TestStringArray
44 | .Select(stringsTestModel => ArrayPoolStringService.ToDashFormat(stringsTestModel.Values))
45 | .Consume(Consumer);
46 | }
47 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Benchmarks/GenerationBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using BenchmarkDotNet.Configs;
4 | using BenchmarkDotNet.Engines;
5 | using BenchmarkDotNet.Order;
6 | using Benchmarks.String.Services;
7 | using MlkPwgen;
8 |
9 | namespace Benchmarks.String.Benchmarks;
10 |
11 | ///
12 | /// String generation benchmarks.
13 | ///
14 | [MemoryDiagnoser, CategoriesColumn, AllStatisticsColumn, Orderer(SummaryOrderPolicy.FastestToSlowest),
15 | GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory), MarkdownExporterAttribute.GitHub, CsvMeasurementsExporter, ExcludeFromCodeCoverage]
16 | public class GenerationBenchmarks
17 | {
18 | private readonly Consumer _consumer = new();
19 |
20 | ///
21 | /// Parameter for models count.
22 | /// **NOTE:** Intentionally left public for BenchmarkDotNet Params.
23 | ///
24 | [Params(10, 100, 1000, 10000, 100000)]
25 | public int GenSize { get; set; }
26 |
27 | ///
28 | /// Gets random string using original method + string.Create.
29 | ///
30 | [Benchmark(Baseline = true)]
31 | public void OriginalRandom()
32 | {
33 | GenerationService.GetUniqueOriginal(GenSize).Consume(_consumer);
34 | }
35 |
36 | ///
37 | /// Gets random string using new method.
38 | ///
39 | [Benchmark]
40 | public void HashSetRandom()
41 | {
42 | GenerationService.GetUniqueHashSet(GenSize).Consume(_consumer);
43 | }
44 |
45 | ///
46 | /// Gets random string using new method with SpanOwner.
47 | ///
48 | [Benchmark]
49 | public void SpanOwnerRandom()
50 | {
51 | GenerationService.GetUniqueSpanOwner(GenSize).Consume(_consumer);
52 | }
53 |
54 | ///
55 | /// Gets random string using new method with ArrayPool.
56 | ///
57 | [Benchmark]
58 | public void ArrayPoolRandom()
59 | {
60 | GenerationService.GetUniqueArrayPool(GenSize).Consume(_consumer);
61 | }
62 |
63 | ///
64 | /// Gets random string using external library created by MlkPwger.
65 | ///
66 | [Benchmark]
67 | public void CryptoMlkPwger()
68 | {
69 | PasswordGenerator.Generate(GenSize).Consume(_consumer);
70 | }
71 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Benchmarks/LinkStringBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using BenchmarkDotNet.Engines;
4 | using Benchmarks.String.Benchmarks.Abstractions;
5 | using Benchmarks.String.Services;
6 |
7 | namespace Benchmarks.String.Benchmarks;
8 |
9 | ///
10 | /// Benchmarking building link.
11 | ///
12 | [ExcludeFromCodeCoverage]
13 | public class LinkStringBenchmarks : BenchmarkCollectionBase
14 | {
15 | ///
16 | /// Generates link format with SpanOwner.
17 | ///
18 | [BenchmarkCategory(Group.LinkFormat), Benchmark]
19 | public void LinkFormatSpanOwner()
20 | {
21 | TestStringArray
22 | .Select(stringsTestModel => SpanOwnerStringService.ToLinkFormat(stringsTestModel.Values))
23 | .Consume(Consumer);
24 | }
25 |
26 | ///
27 | /// Generates link format with regex.
28 | ///
29 | [BenchmarkCategory(Group.LinkFormat), Benchmark]
30 | public void LinkFormatRegex()
31 | {
32 | TestStringArray
33 | .Select(stringsTestModel => RegexStringService.ToLinkFormat(stringsTestModel.Values))
34 | .Consume(Consumer);
35 | }
36 |
37 | ///
38 | /// Generate with ArrayPool.
39 | ///
40 | [BenchmarkCategory(Group.LinkFormat), Benchmark]
41 | public void LinkFormatArrayPool()
42 | {
43 | TestStringArray
44 | .Select(stringsTestModel => ArrayPoolStringService.ToLinkFormat(stringsTestModel.Values))
45 | .Consume(Consumer);
46 | }
47 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Benchmarks/SingleDashStringBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using BenchmarkDotNet.Configs;
4 | using BenchmarkDotNet.Engines;
5 | using BenchmarkDotNet.Order;
6 | using Benchmarks.String.Benchmarks.Abstractions;
7 | using Benchmarks.String.Services;
8 |
9 | namespace Benchmarks.String.Benchmarks;
10 |
11 | ///
12 | /// Benchmarking building link.
13 | ///
14 | ///
15 | /// Base abstraction for benchmarks.
16 | ///
17 | [MemoryDiagnoser, CategoriesColumn, AllStatisticsColumn, Orderer(SummaryOrderPolicy.FastestToSlowest),
18 | GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByParams), MarkdownExporterAttribute.GitHub, CsvMeasurementsExporter, ExcludeFromCodeCoverage]
19 | public class SingleDashStringBenchmarks : BenchmarkBase
20 | {
21 | ///
22 | /// Dash format with SpanOwner.
23 | ///
24 | [BenchmarkCategory(Group.DashView), Benchmark]
25 | public void DashFormatSpanOwner()
26 | {
27 | SpanOwnerStringService.ToDashFormat(TestStringArray.Values).Consume(Consumer);
28 | }
29 |
30 | ///
31 | /// Dash format with SpanOwner.
32 | ///
33 | [BenchmarkCategory(Group.DashView), Benchmark]
34 | public void DashFormatRegex()
35 | {
36 | RegexStringService.ToDashFormat(TestStringArray.Values).Consume(Consumer);
37 | }
38 |
39 | ///
40 | /// Dash format with ArrayPool.
41 | ///
42 | [BenchmarkCategory(Group.DashView), Benchmark]
43 | public void DashFormatArrayPool()
44 | {
45 | ArrayPoolStringService.ToDashFormat(TestStringArray.Values).Consume(Consumer);
46 | }
47 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Benchmarks/SingleLinkStringBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using BenchmarkDotNet.Attributes;
3 | using BenchmarkDotNet.Engines;
4 | using Benchmarks.String.Benchmarks.Abstractions;
5 | using Benchmarks.String.Services;
6 |
7 | namespace Benchmarks.String.Benchmarks;
8 |
9 | ///
10 | /// Benchmarking building link.
11 | ///
12 | [ExcludeFromCodeCoverage]
13 | public class SingleLinkStringBenchmarks : BenchmarkBase
14 | {
15 | ///
16 | /// Generates link format with SpanOwner.
17 | ///
18 | [BenchmarkCategory(Group.LinkFormat), Benchmark]
19 | public void LinkFormatSpanOwner()
20 | {
21 | SpanOwnerStringService.ToLinkFormat(TestStringArray.Values).Consume(Consumer);
22 | }
23 |
24 | ///
25 | /// Generates link format with regex.
26 | ///
27 | [BenchmarkCategory(Group.LinkFormat), Benchmark]
28 | public void LinkFormatRegex()
29 | {
30 | RegexStringService.ToLinkFormat(TestStringArray.Values).Consume(Consumer);
31 | }
32 |
33 | ///
34 | /// Generate with ArrayPool.
35 | ///
36 | [BenchmarkCategory(Group.LinkFormat), Benchmark]
37 | public void LinkFormatArrayPool()
38 | {
39 | ArrayPoolStringService.ToLinkFormat(TestStringArray.Values).Consume(Consumer);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Constants.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.String;
2 |
3 | internal static class Constants
4 | {
5 | internal const string DashedViewDelimiter = " - ";
6 |
7 | internal const char Space = ' ';
8 |
9 | internal const char LinkDelimiter = '-';
10 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
2 | USER $APP_UID
3 | WORKDIR /app
4 |
5 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 | ARG BUILD_CONFIGURATION=Release
7 | WORKDIR /src
8 | COPY ["src/main/Benchmark.String/Benchmark.String.csproj", "src/main/Benchmark.String/"]
9 | RUN dotnet restore "src/main/Benchmark.String/Benchmark.String.csproj"
10 | COPY . .
11 | WORKDIR "/src/src/main/Benchmark.String"
12 | RUN dotnet build "Benchmark.String.csproj" -c $BUILD_CONFIGURATION -o /app/build
13 |
14 | FROM build AS publish
15 | ARG BUILD_CONFIGURATION=Release
16 | RUN dotnet publish "Benchmark.String.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
17 |
18 | FROM base AS final
19 | WORKDIR /app
20 | COPY --from=publish /app/publish .
21 | ENTRYPOINT ["dotnet", "Benchmark.String.dll"]
22 |
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Group.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.String;
2 |
3 | internal static class Group
4 | {
5 | internal const string DashView = "Dash View";
6 |
7 | internal const string LinkFormat = "Link Format";
8 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Models/InterpolationModel.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.String.Models;
2 |
3 | ///
4 | /// Model with interpolation.
5 | ///
6 | public sealed class InterpolationModel
7 | {
8 | ///
9 | /// First value
10 | ///
11 | public string FirstValue { get; set; } = string.Empty;
12 |
13 | ///
14 | /// Second value.
15 | ///
16 | public string SecondValue { get; set; } = string.Empty;
17 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Models/StringsTestModel.cs:
--------------------------------------------------------------------------------
1 | namespace Benchmarks.String.Models;
2 |
3 | ///
4 | /// Model for generating link and dash format.
5 | ///
6 | public sealed class StringsTestModel
7 | {
8 | ///
9 | /// Gets or sets collection of values.
10 | ///
11 | public string[] Values { get; set; } = null!;
12 | }
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 |
3 | BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run();
--------------------------------------------------------------------------------
/src/main/Benchmarks.String/Readme.md:
--------------------------------------------------------------------------------
1 | # Note: this section is going to be refactored
--------------------------------------------------------------------------------
/src/test/Benchmarks.Tests.Unit/Benchmark.Iterators/TestModel.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using Benchmarks.Iterators.Models;
3 |
4 | namespace Benchmarks.Tests.Unit.Benchmark.Iterators;
5 |
6 | ///
7 | /// Unit test model.
8 | ///
9 | public sealed class TestModel
10 | {
11 | ///
12 | /// Constructor.
13 | ///
14 | /// .
15 | public TestModel(SimpleModel simpleModel)
16 | {
17 | SimpleModel = simpleModel;
18 | JsonModel = JsonSerializer.Serialize(simpleModel);
19 | }
20 |
21 | ///
22 | /// Gets .
23 | ///
24 | public SimpleModel SimpleModel { get; }
25 |
26 | ///
27 | /// Gets Json string out of .
28 | ///
29 | public string JsonModel { get; }
30 | }
--------------------------------------------------------------------------------
/src/test/Benchmarks.Tests.Unit/Benchmark.Serializers/Json/JilTests.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Tests.Unit.Benchmark.Serializers.Models;
2 | using FluentAssertions;
3 |
4 | namespace Benchmarks.Tests.Unit.Benchmark.Serializers.Json;
5 |
6 | ///
7 | /// Unit tests of service .
8 | ///
9 | public sealed class JilTests
10 | {
11 | ///
12 | /// Unit testing of method .
13 | ///
14 | [Fact]
15 | public void JilDeserialize_Returns_ValidModels()
16 | {
17 | // Arrange
18 | var actualString = TestsBase.GetTestString();
19 | var expectedModels = TestsBase.GetTestModels();
20 |
21 | // Act
22 | var actualModels = Benchmarks.Serializers.Json.Serializers.JilDeserialize(actualString);
23 |
24 | // Assert
25 | actualModels.Should().BeEquivalentTo(expectedModels);
26 | }
27 |
28 | ///
29 | /// Unit testing of method .
30 | ///
31 | [Fact]
32 | public void JilSerialize_Returns_ValidModel()
33 | {
34 | // Arrange
35 | var expectedModels = TestsBase.GetTestModels();
36 |
37 | // Act
38 | var actualString = Benchmarks.Serializers.Json.Serializers.JilSerialize(expectedModels);
39 | var actualModels = Benchmarks.Serializers.Json.Serializers.JilDeserialize(actualString);
40 |
41 | // Assert
42 | actualModels.Should().BeEquivalentTo(expectedModels);
43 | }
44 |
45 | ///
46 | /// Unit testing of method .
47 | ///
48 | [Fact]
49 | public void JilDeserializeBytes_Returns_ValidModels()
50 | {
51 | // Arrange
52 | var expectedBytes = TestsBase.GetTestBytes();
53 | var expectedModels = TestsBase.GetTestModels();
54 |
55 | // Act
56 | var actualModels = Benchmarks.Serializers.Json.Serializers.JilDeserializeBytes(expectedBytes);
57 |
58 | // Assert
59 | actualModels.Should().BeEquivalentTo(expectedModels);
60 | }
61 |
62 | ///
63 | /// Unit testing of method .
64 | ///
65 | [Fact]
66 | public void JilSerializeBytes_Returns_ValidString()
67 | {
68 | // Arrange
69 | var expectedModels = TestsBase.GetTestModels();
70 |
71 | // Act
72 | var actualBytes = Benchmarks.Serializers.Json.Serializers.JilSerializeBytes(expectedModels);
73 | var actualModels = Benchmarks.Serializers.Json.Serializers.JilDeserializeBytes(actualBytes);
74 |
75 | // Assert
76 | actualModels.Should().BeEquivalentTo(expectedModels);
77 | }
78 | }
--------------------------------------------------------------------------------
/src/test/Benchmarks.Tests.Unit/Benchmark.Serializers/Json/NetJsonTests.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers.Json.Extensions;
2 | using Benchmarks.Tests.Unit.Benchmark.Serializers.Models;
3 | using FluentAssertions;
4 |
5 | namespace Benchmarks.Tests.Unit.Benchmark.Serializers.Json;
6 |
7 | ///
8 | /// Unit tests of .
9 | ///
10 | public class NetJsonTests
11 | {
12 | ///
13 | /// Unit testing of method .
14 | ///
15 | [Fact]
16 | public void NetJsonDeserialize_Returns_ValidModels()
17 | {
18 | // Arrange
19 | var expectedString = TestsBase.GetTestString();
20 | var expectedModels = TestsBase.GetTestModels();
21 |
22 | // Act
23 | var actualString = NetJSON.NetJSON.Serialize(expectedModels);
24 | var actualModels = NetJSON.NetJSON.Deserialize>(actualString, JsonServiceExtensions.NetJsonOptions);
25 |
26 | // Assert
27 | actualModels.Should().BeEquivalentTo(expectedModels);
28 | actualString.Should().BeEquivalentTo(expectedString);
29 | }
30 |
31 | ///
32 | /// Unit testing of method .
33 | ///
34 | [Fact]
35 | public void NetJsonSerialize_Returns_ValidStringModels()
36 | {
37 | // Arrange
38 | var expectedString = TestsBase.GetTestString();
39 | var expectedModels = TestsBase.GetTestModels();
40 |
41 | // Act
42 | var actualString = NetJSON.NetJSON.Serialize(expectedModels, JsonServiceExtensions.NetJsonOptions);
43 |
44 | // // Assert
45 | Assert.Equal(expectedString, actualString);
46 | actualString.Should().BeEquivalentTo(expectedString);
47 | }
48 | }
--------------------------------------------------------------------------------
/src/test/Benchmarks.Tests.Unit/Benchmark.Serializers/Json/NewtonsoftJsonTests.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Benchmarks.Serializers.Json.Extensions;
3 | using Benchmarks.Tests.Unit.Benchmark.Serializers.Models;
4 | using FluentAssertions;
5 | using Newtonsoft.Json;
6 |
7 | namespace Benchmarks.Tests.Unit.Benchmark.Serializers.Json;
8 |
9 | ///
10 | /// Unit tests of service .
11 | ///
12 | public sealed class NewtonsoftJsonTests
13 | {
14 | ///
15 | /// Unit testing of method .
16 | ///
17 | [Fact]
18 | public void NewtonsoftDeserialize_Returns_ValidModels()
19 | {
20 | // Arrange
21 | var actualString = TestsBase.GetTestString();
22 | var expectedModels = TestsBase.GetTestModels();
23 |
24 | // Act
25 | var actualModels = JsonConvert.DeserializeObject(actualString, JsonServiceExtensions.NewtonsoftOptions);
26 |
27 | // Assert
28 | actualModels.Should().BeEquivalentTo(expectedModels);
29 | }
30 |
31 | ///
32 | /// Unit testing of method .
33 | ///
34 | [Fact]
35 | public void NewtonsoftSerialize_Returns_ValidString()
36 | {
37 | // Arrange
38 | var expectedString = TestsBase.GetTestString();
39 | var expectedModels = TestsBase.GetTestModels();
40 |
41 | // Act
42 | var actualString = JsonConvert.SerializeObject(expectedModels, Formatting.None, JsonServiceExtensions.NewtonsoftOptions);
43 |
44 | // Assert
45 | actualString.Should().BeEquivalentTo(expectedString);
46 | }
47 |
48 | ///
49 | /// Unit testing of method .
50 | ///
51 | [Fact]
52 | public void NewtonsoftDeserializeBytes_Returns_ValidModels()
53 | {
54 | // Arrange
55 | var actualBytes = TestsBase.GetTestBytes();
56 | var expectedModels = TestsBase.GetTestModels();
57 |
58 | // Act
59 | var actualModels = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(actualBytes), JsonServiceExtensions.NewtonsoftOptions);
60 |
61 | // Assert
62 | actualModels.Should().BeEquivalentTo(expectedModels);
63 | }
64 | }
--------------------------------------------------------------------------------
/src/test/Benchmarks.Tests.Unit/Benchmark.Serializers/Json/ServiceStackTests.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Serializers.Json.Extensions;
2 | using Benchmarks.Tests.Unit.Benchmark.Serializers.Models;
3 | using FluentAssertions;
4 | using ServiceStack.Text;
5 |
6 | namespace Benchmarks.Tests.Unit.Benchmark.Serializers.Json;
7 |
8 | ///
9 | /// Unit tests of service
10 | ///
11 | public sealed class ServiceStackTests
12 | {
13 | ///
14 | /// Unit testing of method .
15 | ///
16 | [Fact]
17 | public void ServiceStackDeserialize_Returns_ValidModels()
18 | {
19 | // Arrange
20 | var actualString = TestsBase.GetTestString();
21 | var expectedModels = TestsBase.GetTestModels();
22 |
23 | // Act
24 | TestModel[] actualModels;
25 |
26 | using (JsConfig.With(JsonServiceExtensions.ServiceStackOptions))
27 | {
28 | actualModels = JsonSerializer.DeserializeFromSpan(actualString);
29 | }
30 |
31 | // Assert
32 | actualModels.Should().BeEquivalentTo(expectedModels);
33 | }
34 |
35 | ///
36 | /// Unit testing of method .
37 | ///
38 | [Fact]
39 | public void ServiceStackDeserialize_Returns_ValidStringModels()
40 | {
41 | // Arrange
42 | var expectedModels = TestsBase.GetTestModels();
43 |
44 | // Act
45 | TestModel[] actualModels;
46 |
47 | using (JsConfig.With(JsonServiceExtensions.ServiceStackOptions))
48 | {
49 | var actualString = JsonSerializer.SerializeToString(expectedModels);
50 | actualModels = JsonSerializer.DeserializeFromSpan(actualString);
51 | }
52 |
53 | // Assert
54 | actualModels.Should().BeEquivalentTo(expectedModels);
55 | }
56 | }
--------------------------------------------------------------------------------
/src/test/Benchmarks.Tests.Unit/Benchmark.Serializers/Json/SpanJsonTests.cs:
--------------------------------------------------------------------------------
1 | using Benchmarks.Tests.Unit.Benchmark.Serializers.Models;
2 | using FluentAssertions;
3 | using SpanJson;
4 |
5 | namespace Benchmarks.Tests.Unit.Benchmark.Serializers.Json;
6 |
7 | ///
8 | /// Unit tests of service .
9 | ///
10 | public sealed class SpanJsonTests
11 | {
12 | ///
13 | /// Unit testing of method .
14 | ///
15 | [Fact]
16 | public void SpanJsonDeserialize_Returns_ValidModels()
17 | {
18 | // Arrange
19 | var actualString = TestsBase.GetTestString();
20 | var expectedModels = TestsBase.GetTestModels();
21 |
22 | // Act
23 | var actualModels = JsonSerializer.Generic.Utf16.Deserialize(actualString);
24 |
25 | // Assert
26 | actualModels.Should().BeEquivalentTo(expectedModels);
27 | }
28 |
29 | ///
30 | /// Unit testing of method .
31 | ///
32 | [Fact]
33 | public void SpanJsonSerialize_Returns_ValidString()
34 | {
35 | // Arrange
36 | var expectedString = TestsBase.GetTestString();
37 | var expectedModels = TestsBase.GetTestModels();
38 |
39 | // Act
40 | var actualString = JsonSerializer.Generic.Utf16.Serialize(expectedModels);
41 |
42 | // Assert
43 | Assert.Equal(expectedString, actualString);
44 | actualString.Should().BeEquivalentTo(expectedString);
45 | }
46 |
47 | ///
48 | /// Unit testing of method .
49 | ///
50 | [Fact]
51 | public void SpanJsonDeserializeBytes_Returns_ValidModels()
52 | {
53 | // Arrange
54 | var expectedBytes = TestsBase.GetTestBytes();
55 | var expectedModels = TestsBase.GetTestModels();
56 |
57 | // Act
58 | var actualModels = JsonSerializer.Generic.Utf8.Deserialize(expectedBytes);
59 |
60 | // Assert
61 | actualModels.Should().BeEquivalentTo(expectedModels);
62 | }
63 |
64 | ///
65 | /// Unit testing of method .
66 | ///
67 | [Fact]
68 | public void SpanJsonSerializeBytes_Returns_ValidString()
69 | {
70 | // Arrange
71 | var expectedModels = TestsBase.GetTestModels();
72 |
73 | // Act
74 | var actualBytes = JsonSerializer.Generic.Utf8.Serialize(expectedModels);
75 | var actualModels = JsonSerializer.Generic.Utf8.Deserialize(actualBytes);
76 |
77 | // Assert
78 | actualModels.Should().BeEquivalentTo(expectedModels);
79 | }
80 | }
--------------------------------------------------------------------------------
/src/test/Benchmarks.Tests.Unit/Benchmark.Serializers/Json/SystemTextJsonTests.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json;
2 | using Benchmarks.Tests.Unit.Benchmark.Serializers.Models;
3 | using FluentAssertions;
4 |
5 | namespace Benchmarks.Tests.Unit.Benchmark.Serializers.Json;
6 |
7 | ///
8 | /// Unit tests of
9 | ///
10 | public sealed class SystemTextJsonTests
11 | {
12 | ///
13 | /// Unit testing of method .
14 | ///
15 | [Fact]
16 | public void SystemTextJsonDeserialize_Returns_ValidModels()
17 | {
18 | // Arrange
19 | var actualString = TestsBase.GetTestString();
20 | var expectedModels = TestsBase.GetTestModels();
21 |
22 | // Act
23 | var actualModels = JsonSerializer.Deserialize(actualString);
24 |
25 | // Assert
26 | actualModels.Should().BeEquivalentTo(expectedModels);
27 | }
28 |
29 | ///
30 | /// Unit testing of method .
31 | ///
32 | [Fact]
33 | public void SystemTextJsonSerialize_Returns_ValidString()
34 | {
35 | // Arrange
36 | var expectedString = TestsBase.GetTestString();
37 | var expectedModels = TestsBase.GetTestModels();
38 |
39 | // Act
40 | var actualString = JsonSerializer.Serialize(expectedModels);
41 |
42 | // Assert
43 | actualString.Should().BeEquivalentTo(expectedString);
44 | }
45 |
46 | ///
47 | /// Unit testing of method .
48 | ///
49 | [Fact]
50 | public void SystemTextJsonDeserializeBytes_Returns_ValidModels()
51 | {
52 | // Arrange
53 | var expectedBytes = TestsBase.GetTestBytes();
54 | var expectedModels = TestsBase.GetTestModels();
55 |
56 | // Act
57 | var actualModels = JsonSerializer.Deserialize(expectedBytes);
58 |
59 | // Assert
60 | actualModels.Should().BeEquivalentTo(expectedModels);
61 | }
62 |
63 | ///
64 | /// Unit testing of method .
65 | ///
66 | [Fact]
67 | public void SystemTextJsonSerializeBytes_Returns_ValidString()
68 | {
69 | // Arrange
70 | var expectedBytes = TestsBase.GetTestBytes();
71 | var expectedModels = TestsBase.GetTestModels();
72 |
73 | // Act
74 | var actualBytes = JsonSerializer.SerializeToUtf8Bytes(expectedModels);
75 |
76 | // Assert
77 | actualBytes.Should().BeEquivalentTo(expectedBytes);
78 | }
79 | }
--------------------------------------------------------------------------------
/src/test/Benchmarks.Tests.Unit/Benchmark.Serializers/Json/TestsBase.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Benchmarks.Tests.Unit.Benchmark.Serializers.Models;
3 | using Bogus;
4 |
5 | namespace Benchmarks.Tests.Unit.Benchmark.Serializers.Json;
6 |
7 | ///
8 | /// Base class with arranged values.
9 | ///
10 | public static class TestsBase
11 | {
12 | private const int InternalCount = 10;
13 |
14 | private readonly static Faker TestModelFaker = new();
15 |
16 | private readonly static TestModel[] TestModels = TestModelFaker
17 | .RuleFor(testModel => testModel.TestByte, fakerSetter => fakerSetter.Random.Byte())
18 | .RuleFor(testModel => testModel.TestChar, fakerSetter => fakerSetter.Random.Char('a', 'z'))
19 | .RuleFor(testModel => testModel.TestDouble, fakerSetter => double.Parse(fakerSetter.Random.Double().ToString("N4")))
20 | .RuleFor(testModel => testModel.TestFloat, fakerSetter => fakerSetter.Random.Float())
21 | .RuleFor(testModel => testModel.TestInt, fakerSetter => fakerSetter.Random.Int())
22 | .RuleFor(testModel => testModel.TestLong, fakerSetter => fakerSetter.Random.Long())
23 | .RuleFor(testModel => testModel.TestShort, fakerSetter => fakerSetter.Random.Short())
24 | .RuleFor(testModel => testModel.TestString, fakerSetter => fakerSetter.Random.String2(5, 10))
25 | .RuleFor(testModel => testModel.TestUInt, fakerSetter => fakerSetter.Random.UInt())
26 | .RuleFor(testModel => testModel.TestUShort, fakerSetter => fakerSetter.Random.UShort())
27 | .RuleFor(testModel => testModel.TestULong, fakerSetter => fakerSetter.Random.ULong())
28 | .Generate(InternalCount)
29 | .ToArray();
30 |
31 | private readonly static string TestString = BuildString(TestModels);
32 |
33 | ///
34 | /// Gets built constructed string.
35 | ///
36 | /// built constructed string.
37 | public static string GetTestString()
38 | {
39 | return TestString;
40 | }
41 |
42 | ///
43 | /// Gets array of bytes from string value.
44 | ///
45 | /// Array of bytes from string value.
46 | public static byte[] GetTestBytes()
47 | {
48 | return Encoding.UTF8.GetBytes(TestString);
49 | }
50 |
51 | ///
52 | /// Gets List of .
53 | ///
54 | /// List of .
55 | public static TestModel[] GetTestModels()
56 | {
57 | return TestModels;
58 | }
59 |
60 | private static string BuildString(Span testModels)
61 | {
62 | var sb = new StringBuilder();
63 | sb.Append('[');
64 |
65 | for (var i = 0; i < testModels.Length - 1; i++)
66 | {
67 | sb.Append(testModels[i]);
68 | sb.Append(',');
69 | }
70 |
71 | sb.Append(testModels[^1]);
72 | sb.Append(']');
73 |
74 | return sb.ToString();
75 | }
76 | }
--------------------------------------------------------------------------------
/src/test/Benchmarks.Tests.Unit/Benchmark.Serializers/Json/Utf8JsonTests.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Benchmarks.Tests.Unit.Benchmark.Serializers.Models;
3 | using FluentAssertions;
4 | using Utf8Json;
5 |
6 | namespace Benchmarks.Tests.Unit.Benchmark.Serializers.Json;
7 |
8 | ///
9 | /// Unit tests for service .
10 | ///
11 | public sealed class Utf8JsonTests
12 | {
13 | ///
14 | /// Unit testing of method .
15 | ///
16 | [Fact]
17 | public void Utf8JsonDeserialize_Returns_ValidModels()
18 | {
19 | // Arrange
20 | var actualString = TestsBase.GetTestString();
21 | var expectedModels = TestsBase.GetTestModels();
22 |
23 | // Act
24 | var actualModels = JsonSerializer.Deserialize(actualString)!;
25 |
26 | // Assert
27 | actualModels.Should().BeEquivalentTo(expectedModels);
28 | }
29 |
30 | ///
31 | /// Unit testing of method