Skip to content

Commit bc44688

Browse files
committed
push project for microbenchmarks
1 parent e3726ec commit bc44688

File tree

4 files changed

+139
-1
lines changed

4 files changed

+139
-1
lines changed

AspNetCore.slnx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@
161161
<Project Path="src/DataProtection/Abstractions/src/Microsoft.AspNetCore.DataProtection.Abstractions.csproj" />
162162
<Project Path="src/DataProtection/Abstractions/test/Microsoft.AspNetCore.DataProtection.Abstractions.Tests.csproj" />
163163
</Folder>
164+
<Folder Name="/src/DataProtection/benchmarks/">
165+
<Project Path="src/DataProtection/benchmarks/Microsoft.AspNetCore.DataProtection.MicroBenchmarks/Microsoft.AspNetCore.DataProtection.MicroBenchmarks.csproj" Id="71744108-dc12-4558-9788-ed62c9f0441c" />
166+
</Folder>
164167
<Folder Name="/src/DataProtection/Cryptography.Internal/">
165168
<Project Path="src/DataProtection/Cryptography.Internal/src/Microsoft.AspNetCore.Cryptography.Internal.csproj" />
166169
<Project Path="src/DataProtection/Cryptography.Internal/test/Microsoft.AspNetCore.Cryptography.Internal.Tests.csproj" />
@@ -1143,6 +1146,7 @@
11431146
<Project Path="src/SignalR/server/StackExchangeRedis/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj" />
11441147
<Project Path="src/SignalR/server/StackExchangeRedis/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests.csproj" />
11451148
</Folder>
1149+
<Folder Name="/src/SiteExtensions/" />
11461150
<Folder Name="/src/SiteExtensions/Microsoft.Web.Xdt.Extensions/">
11471151
<Project Path="src/SiteExtensions/Microsoft.Web.Xdt.Extensions/src/Microsoft.Web.Xdt.Extensions.csproj" />
11481152
<Project Path="src/SiteExtensions/Microsoft.Web.Xdt.Extensions/tests/Microsoft.Web.Xdt.Extensions.Tests.csproj" />
@@ -1190,8 +1194,8 @@
11901194
<Project Path="src/Validation/src/Microsoft.Extensions.Validation.csproj" />
11911195
</Folder>
11921196
<Folder Name="/src/Validation/test/">
1193-
<Project Path="src/Validation/test/Microsoft.Extensions.Validation.Tests/Microsoft.Extensions.Validation.Tests.csproj" />
11941197
<Project Path="src/Validation/test/Microsoft.Extensions.Validation.GeneratorTests/Microsoft.Extensions.Validation.GeneratorTests.csproj" />
1198+
<Project Path="src/Validation/test/Microsoft.Extensions.Validation.Tests/Microsoft.Extensions.Validation.Tests.csproj" />
11951199
</Folder>
11961200
<Folder Name="/src/WebEncoders/">
11971201
<Project Path="src/WebEncoders/src/Microsoft.Extensions.WebEncoders.csproj" />

src/DataProtection/DataProtection.slnf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"src\\DataProtection\\Extensions\\test\\Microsoft.AspNetCore.DataProtection.Extensions.Tests.csproj",
1717
"src\\DataProtection\\StackExchangeRedis\\src\\Microsoft.AspNetCore.DataProtection.StackExchangeRedis.csproj",
1818
"src\\DataProtection\\StackExchangeRedis\\test\\Microsoft.AspNetCore.DataProtection.StackExchangeRedis.Tests.csproj",
19+
"src\\DataProtection\\benchmarks\\Microsoft.AspNetCore.DataProtection.MicroBenchmarks\\Microsoft.AspNetCore.DataProtection.MicroBenchmarks.csproj",
1920
"src\\DataProtection\\samples\\CustomEncryptorSample\\CustomEncryptorSample.csproj",
2021
"src\\DataProtection\\samples\\EntityFrameworkCoreSample\\EntityFrameworkCoreSample.csproj",
2122
"src\\DataProtection\\samples\\KeyManagementSample\\KeyManagementSample.csproj",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
5+
<OutputType>Exe</OutputType>
6+
<ServerGarbageCollection>true</ServerGarbageCollection>
7+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
8+
<TieredCompilation>false</TieredCompilation>
9+
<DefineConstants>$(DefineConstants);IS_BENCHMARKS</DefineConstants>
10+
<SkipMicrobenchmarksValidation>true</SkipMicrobenchmarksValidation>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<Reference Include="BenchmarkDotNet" />
15+
<Reference Include="Microsoft.AspNetCore.DataProtection" />
16+
<Reference Include="Microsoft.Extensions.DependencyInjection" />
17+
</ItemGroup>
18+
19+
<ItemGroup>
20+
<Compile Include="$(SharedSourceRoot)BenchmarkRunner\*.cs" />
21+
</ItemGroup>
22+
23+
</Project>
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Buffers;
5+
using BenchmarkDotNet.Attributes;
6+
using Microsoft.Extensions.DependencyInjection;
7+
8+
namespace Microsoft.AspNetCore.DataProtection.MicroBenchmarks;
9+
10+
[SimpleJob, MemoryDiagnoser]
11+
public class SpanDataProtectorComparison
12+
{
13+
private IDataProtector _dataProtector = null!;
14+
private ISpanDataProtector _spanDataProtector = null!;
15+
16+
private byte[] _plaintext5 = null!;
17+
private byte[] _plaintext50 = null!;
18+
private byte[] _plaintext100 = null!;
19+
20+
[Params(5, 50, 100)]
21+
public int PlaintextLength { get; set; }
22+
23+
[GlobalSetup]
24+
public void Setup()
25+
{
26+
// Setup DataProtection as in DI
27+
var services = new ServiceCollection();
28+
services.AddDataProtection();
29+
var serviceProvider = services.BuildServiceProvider();
30+
31+
_dataProtector = serviceProvider.GetDataProtector("benchmark", "test");
32+
_spanDataProtector = (ISpanDataProtector)_dataProtector;
33+
34+
// Setup test data for different lengths
35+
var random = new Random(42); // Fixed seed for consistent results
36+
37+
_plaintext5 = new byte[5];
38+
random.NextBytes(_plaintext5);
39+
40+
_plaintext50 = new byte[50];
41+
random.NextBytes(_plaintext50);
42+
43+
_plaintext100 = new byte[100];
44+
random.NextBytes(_plaintext100);
45+
}
46+
47+
private byte[] GetPlaintext()
48+
{
49+
return PlaintextLength switch
50+
{
51+
5 => _plaintext5,
52+
50 => _plaintext50,
53+
100 => _plaintext100,
54+
_ => throw new ArgumentException("Invalid plaintext length")
55+
};
56+
}
57+
58+
[Benchmark]
59+
public void ProtectUnprotectRoundtrip()
60+
{
61+
var plaintext = GetPlaintext();
62+
63+
// Traditional approach with allocations
64+
var protectedData = _dataProtector.Protect(plaintext);
65+
var unprotectedData = _dataProtector.Unprotect(protectedData);
66+
}
67+
68+
[Benchmark]
69+
public void TryProtectTryUnprotectRoundtrip()
70+
{
71+
var plaintext = GetPlaintext();
72+
73+
// Span-based approach with minimal allocations
74+
var protectedSize = _spanDataProtector.GetProtectedSize(plaintext.Length);
75+
var protectedBuffer = ArrayPool<byte>.Shared.Rent(protectedSize);
76+
77+
try
78+
{
79+
var protectSuccess = _spanDataProtector.TryProtect(plaintext, protectedBuffer, out var protectedBytesWritten);
80+
if (!protectSuccess)
81+
{
82+
throw new InvalidOperationException("TryProtect failed");
83+
}
84+
85+
var unprotectedSize = _spanDataProtector.GetUnprotectedSize(protectedBytesWritten);
86+
var unprotectedBuffer = ArrayPool<byte>.Shared.Rent(unprotectedSize);
87+
88+
try
89+
{
90+
var unprotectSuccess = _spanDataProtector.TryUnprotect(
91+
protectedBuffer.AsSpan(0, protectedBytesWritten),
92+
unprotectedBuffer,
93+
out var unprotectedBytesWritten);
94+
95+
if (!unprotectSuccess)
96+
{
97+
throw new InvalidOperationException("TryUnprotect failed");
98+
}
99+
}
100+
finally
101+
{
102+
ArrayPool<byte>.Shared.Return(unprotectedBuffer);
103+
}
104+
}
105+
finally
106+
{
107+
ArrayPool<byte>.Shared.Return(protectedBuffer);
108+
}
109+
}
110+
}

0 commit comments

Comments
 (0)