Skip to content

Commit 3e4cf21

Browse files
authored
Add benchmark github action (#97)
1 parent e99ec77 commit 3e4cf21

10 files changed

Lines changed: 357 additions & 72 deletions

File tree

.github/workflows/benchmark.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: Benchmarker
2+
TODO use this before merging
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
deployments: write
11+
12+
jobs:
13+
temporal:
14+
name: Temporal Marshalling
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: actions/setup-dotnet@v3
19+
with:
20+
dotnet-version: 8.0.x
21+
- name: Run
22+
run: dotnet run --project tests/DynamoDBGenerator.SourceGenerator.Benchmarks --configuration 'Release' -- --exporters 'JSON' --filter '*TemporalBenchmarks*' --memory --job 'Default'
23+
- name: Store
24+
uses: rhysd/github-action-benchmark@v1
25+
with:
26+
name: Temporal Marshalling
27+
tool: 'benchmarkdotnet'
28+
output-file-path: BenchmarkDotNet.Artifacts/results/DynamoDBGenerator.SourceGenerator.Benchmarks.Benchmarks.Marshalling.TemporalBenchmarks-report-full-compressed.json
29+
github-token: ${{ secrets.GITHUB_TOKEN }}
30+
auto-push: true
31+
# Show alert with commit comment on detecting possible performance regression
32+
alert-threshold: '200%'
33+
benchmark-data-dir-path: 'benchmarks/marshalling/temporal'
34+
comment-on-alert: true
35+
fail-on-alert: true
36+
alert-comment-cc-users: '@inputfalken'
37+
primitve:
38+
name: Primitive Marshalling
39+
runs-on: ubuntu-latest
40+
steps:
41+
- uses: actions/checkout@v4
42+
- uses: actions/setup-dotnet@v3
43+
with:
44+
dotnet-version: 8.0.x
45+
- name: Run
46+
run: dotnet run --project tests/DynamoDBGenerator.SourceGenerator.Benchmarks --configuration 'Release' -- --exporters 'JSON' --filter '*PrimitiveBenchmarks*' --memory --job 'Default'
47+
- name: Store
48+
uses: rhysd/github-action-benchmark@v1
49+
with:
50+
name: Primitive Marshalling
51+
tool: 'benchmarkdotnet'
52+
output-file-path: BenchmarkDotNet.Artifacts/results/DynamoDBGenerator.SourceGenerator.Benchmarks.Benchmarks.Marshalling.PrimitiveBenchmarks-report-full-compressed.json
53+
github-token: ${{ secrets.GITHUB_TOKEN }}
54+
benchmark-data-dir-path: 'benchmarks/marshalling/primitive'
55+
auto-push: true
56+
# Show alert with commit comment on detecting possible performance regression
57+
alert-threshold: '200%'
58+
comment-on-alert: true
59+
fail-on-alert: true
60+
alert-comment-cc-users: '@inputfalken'
61+
collection:
62+
name: Collection Marshalling
63+
runs-on: ubuntu-latest
64+
steps:
65+
- uses: actions/checkout@v4
66+
- uses: actions/setup-dotnet@v3
67+
with:
68+
dotnet-version: 8.0.x
69+
- name: Run
70+
run: dotnet run --project tests/DynamoDBGenerator.SourceGenerator.Benchmarks --configuration 'Release' -- --exporters 'JSON' --filter '*CollectionBenchmarks*' --memory --job 'Default'
71+
- name: Store
72+
uses: rhysd/github-action-benchmark@v1
73+
with:
74+
name: Collection Marshalling
75+
tool: 'benchmarkdotnet'
76+
output-file-path: BenchmarkDotNet.Artifacts/results/DynamoDBGenerator.SourceGenerator.Benchmarks.Benchmarks.Marshalling.CollectionBenchmarks-report-full-compressed.json
77+
github-token: ${{ secrets.GITHUB_TOKEN }}
78+
auto-push: true
79+
benchmark-data-dir-path: 'benchmarks/marshalling/collection'
80+
# Show alert with commit comment on detecting possible performance regression
81+
alert-threshold: '200%'
82+
comment-on-alert: true
83+
fail-on-alert: true
84+
alert-comment-cc-users: '@inputfalken'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
namespace DynamoDBGenerator.SourceGenerator.Benchmarks.Benchmarks;
2+
3+
public sealed record Container<T>(T Value);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace DynamoDBGenerator.SourceGenerator.Benchmarks.Benchmarks.Dtos;
2+
3+
//[SimpleJob(RuntimeMoniker.Net80)]
4+
//[MemoryDiagnoser]
5+
//public class PersonBenchmarker() : MarshalBenchmarker<PersonEntity>(
6+
// PersonEntity.PersonEntityMarshaller.Marshall,
7+
// PersonEntity.PersonEntityMarshaller.Unmarshall
8+
//);
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System.Runtime.CompilerServices;
2+
using Amazon.DynamoDBv2.Model;
3+
using AutoFixture;
4+
5+
namespace DynamoDBGenerator.SourceGenerator.Benchmarks.Benchmarks.Marshalling;
6+
7+
public class DynamoDbMarshallerBenchmarkHelper<T, T2, T3, T4>
8+
where T4 : IAttributeExpressionValueTracker<T2>
9+
where T3 : IAttributeExpressionNameTracker
10+
{
11+
private readonly IDynamoDBMarshaller<T, T2, T3, T4> _marshaller;
12+
private readonly T _element;
13+
private readonly Dictionary<string, AttributeValue> _attributeValues;
14+
15+
public DynamoDbMarshallerBenchmarkHelper(IDynamoDBMarshaller<T, T2, T3, T4> marshaller)
16+
{
17+
_marshaller = marshaller;
18+
_element = SetupFixture().Create<T>();
19+
_attributeValues = marshaller.Marshall(_element);
20+
}
21+
22+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
23+
public T Unmarshall() => _marshaller.Unmarshall(_attributeValues);
24+
25+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
26+
public Dictionary<string, AttributeValue> Marshall() => _marshaller.Marshall(_element);
27+
28+
private static Fixture SetupFixture()
29+
{
30+
var fixture = new Fixture();
31+
fixture.Customize<DateOnly>(o => o.FromFactory((DateTime dt) => DateOnly.FromDateTime(dt)));
32+
fixture.Customize<TimeOnly>(o => o.FromFactory((DateTime dt) => TimeOnly.FromDateTime(dt)));
33+
// Allow recursive types
34+
fixture.Behaviors
35+
.OfType<ThrowingRecursionBehavior>()
36+
.ToList()
37+
.ForEach(b => fixture.Behaviors.Remove(b));
38+
fixture.Behaviors.Add(new OmitOnRecursionBehavior());
39+
return fixture;
40+
}
41+
}
42+
43+
public static class Extensions
44+
{
45+
public static DynamoDbMarshallerBenchmarkHelper<T, T2, T3, T4> ToBenchmarkHelper<T, T2, T3, T4>(
46+
this IDynamoDBMarshaller<T, T2, T3, T4> marshaller) where T3 : IAttributeExpressionNameTracker
47+
where T4 : IAttributeExpressionValueTracker<T2>
48+
{
49+
return new DynamoDbMarshallerBenchmarkHelper<T, T2, T3, T4>(marshaller);
50+
}
51+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Amazon.DynamoDBv2.Model;
2+
using BenchmarkDotNet.Attributes;
3+
using DynamoDBGenerator.Attributes;
4+
5+
namespace DynamoDBGenerator.SourceGenerator.Benchmarks.Benchmarks.Marshalling;
6+
7+
[DynamoDBMarshaller(EntityType = typeof(Container<Dictionary<string, int>>), AccessName = "DictionaryMarshaller")]
8+
[DynamoDBMarshaller(EntityType = typeof(Container<HashSet<string>>), AccessName = "StringHashSetMarshaller")]
9+
[DynamoDBMarshaller(EntityType = typeof(Container<List<string>>), AccessName = "ListMarshaller")]
10+
[DynamoDBMarshaller(EntityType = typeof(Container<HashSet<int>>), AccessName = "IntHashSetMarshaller")]
11+
[DynamoDBMarshaller(EntityType = typeof(Container<List<KeyValuePair<string, int>>>), AccessName = "KeyValuePairListMarshaller")]
12+
public partial class CollectionBenchmarks
13+
{
14+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<Dictionary<string, int>>, Container<Dictionary<string, int>>, ContainerDictionarystringintNames, ContainerDictionarystringintValues> _dictionary = DictionaryMarshaller.ToBenchmarkHelper();
15+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<HashSet<string>>, Container<HashSet<string>>, ContainerHashSetstringNames, ContainerHashSetstringValues> _stringHashSet = StringHashSetMarshaller.ToBenchmarkHelper();
16+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<List<string>>, Container<List<string>>, ContainerListstringNames, ContainerListstringValues> _stringList = ListMarshaller.ToBenchmarkHelper();
17+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<HashSet<int>>, Container<HashSet<int>>, ContainerHashSetintNames, ContainerHashSetintValues> _intHashSet = IntHashSetMarshaller.ToBenchmarkHelper();
18+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<List<KeyValuePair<string, int>>>, Container<List<KeyValuePair<string, int>>>, ContainerListKeyValuePairstringintNames, ContainerListKeyValuePairstringintValues> _keyValuePairList = KeyValuePairListMarshaller.ToBenchmarkHelper();
19+
20+
[Benchmark]
21+
public Container<Dictionary<string, int>> Unmarshall_Dictionary() => _dictionary.Unmarshall();
22+
23+
[Benchmark]
24+
public Dictionary<string, AttributeValue> Marshall_Dictionary() => _dictionary.Marshall();
25+
26+
[Benchmark]
27+
public Container<HashSet<string>> Unmarshall_StringHashSet() => _stringHashSet.Unmarshall();
28+
29+
[Benchmark]
30+
public Dictionary<string, AttributeValue> Marshall_StringHashSet() => _stringHashSet.Marshall();
31+
32+
[Benchmark]
33+
public Container<List<string>> Unmarshall_StringList() => _stringList.Unmarshall();
34+
35+
[Benchmark]
36+
public Dictionary<string, AttributeValue> Marshall_StringList() => _stringList.Marshall();
37+
38+
[Benchmark]
39+
public Container<HashSet<int>> Unmarshall_IntHashSet() => _intHashSet.Unmarshall();
40+
41+
[Benchmark]
42+
public Dictionary<string, AttributeValue> Marshall_IntHashSet() => _intHashSet.Marshall();
43+
44+
[Benchmark]
45+
public Container<List<KeyValuePair<string,int>>> Unmarshall_KeyValuePairList() => _keyValuePairList.Unmarshall();
46+
47+
[Benchmark]
48+
public Dictionary<string, AttributeValue> Marshall_KeyValuePairList() => _keyValuePairList.Marshall();
49+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using Amazon.DynamoDBv2.Model;
2+
using BenchmarkDotNet.Attributes;
3+
using DynamoDBGenerator.Attributes;
4+
5+
namespace DynamoDBGenerator.SourceGenerator.Benchmarks.Benchmarks.Marshalling;
6+
7+
[DynamoDBMarshaller(EntityType = typeof(Container<bool>), AccessName = "BooleanMarshaller")]
8+
[DynamoDBMarshaller(EntityType = typeof(Container<char>), AccessName = "CharMarshaller")]
9+
[DynamoDBMarshaller(EntityType = typeof(Container<int>), AccessName = "Int32Marshaller")]
10+
[DynamoDBMarshaller(EntityType = typeof(Container<long>), AccessName = "Int64Marshaller")]
11+
[DynamoDBMarshaller(EntityType = typeof(Container<string>), AccessName = "StringMarshaller")]
12+
[DynamoDBMarshaller(EntityType = typeof(Container<uint>), AccessName = "UInt32Marshaller")]
13+
[DynamoDBMarshaller(EntityType = typeof(Container<ulong>), AccessName = "UInt64Marshaller")]
14+
[DynamoDBMarshaller(EntityType = typeof(Container<Guid>), AccessName = "GuidMarshaller")]
15+
[DynamoDBMarshaller(EntityType = typeof(Container<DayOfWeek>), AccessName = "EnumMarshaller")]
16+
[DynamoDBMarshaller(EntityType = typeof(Container<double>), AccessName = "DoubleMarshaller")]
17+
public partial class PrimitiveBenchmarks
18+
{
19+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<bool>, Container<bool>, ContainerboolNames, ContainerboolValues> _bool = BooleanMarshaller.ToBenchmarkHelper();
20+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<char>, Container<char>, ContainercharNames, ContainercharValues> _char = CharMarshaller.ToBenchmarkHelper();
21+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<int>, Container<int>, ContainerintNames, ContainerintValues> _int = Int32Marshaller.ToBenchmarkHelper();
22+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<long>, Container<long>, ContainerlongNames, ContainerlongValues> _long = Int64Marshaller.ToBenchmarkHelper();
23+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<string>, Container<string>, ContainerstringNames, ContainerstringValues> _string = StringMarshaller.ToBenchmarkHelper();
24+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<uint>, Container<uint>, ContaineruintNames, ContaineruintValues> _uint = UInt32Marshaller.ToBenchmarkHelper();
25+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<ulong>, Container<ulong>, ContainerulongNames, ContainerulongValues> _ulong = UInt64Marshaller.ToBenchmarkHelper();
26+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<Guid>, Container<Guid>, ContainerGuidNames, ContainerGuidValues> _guid = GuidMarshaller.ToBenchmarkHelper();
27+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<DayOfWeek>, Container<DayOfWeek>, ContainerDayOfWeekNames, ContainerDayOfWeekValues> _enum = EnumMarshaller.ToBenchmarkHelper();
28+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<double>, Container<double>, ContainerdoubleNames, ContainerdoubleValues> _double = DoubleMarshaller.ToBenchmarkHelper();
29+
30+
[Benchmark]
31+
public Container<bool> Unmarshall_Bool() => _bool.Unmarshall();
32+
33+
[Benchmark]
34+
public Dictionary<string, AttributeValue> Marshall_Bool() => _bool.Marshall();
35+
36+
[Benchmark]
37+
public Container<char> Unmarshall_Char() => _char.Unmarshall();
38+
39+
[Benchmark]
40+
public Dictionary<string, AttributeValue> Marshall_Char() => _char.Marshall();
41+
42+
[Benchmark]
43+
public Container<int> Unmarshall_Int32() => _int.Unmarshall();
44+
45+
[Benchmark]
46+
public Dictionary<string, AttributeValue> Marshall_Int() => _int.Marshall();
47+
48+
[Benchmark]
49+
public Container<long> Unmarshall_Int64() => _long.Unmarshall();
50+
51+
[Benchmark]
52+
public Dictionary<string, AttributeValue> Marshall_Int64() => _long.Marshall();
53+
54+
[Benchmark]
55+
public Container<string> Unmarshall_String() => _string.Unmarshall();
56+
57+
[Benchmark]
58+
public Dictionary<string, AttributeValue> Marshall_String() => _string.Marshall();
59+
60+
[Benchmark]
61+
public Container<uint> Unmarshall_UInt32() => _uint.Unmarshall();
62+
63+
[Benchmark]
64+
public Dictionary<string, AttributeValue> Marshall_UInt32() => _uint.Marshall();
65+
66+
[Benchmark]
67+
public Container<ulong> Unmarshall_UInt64() => _ulong.Unmarshall();
68+
69+
[Benchmark]
70+
public Dictionary<string, AttributeValue> Marshall_Uint64() => _ulong.Marshall();
71+
72+
[Benchmark]
73+
public Container<Guid> Unmarshall_Guid() => _guid.Unmarshall();
74+
75+
[Benchmark]
76+
public Dictionary<string, AttributeValue> Marshall_Guid() => _guid.Marshall();
77+
78+
[Benchmark]
79+
public Container<DayOfWeek> Unmarshall_Enum() => _enum.Unmarshall();
80+
81+
[Benchmark]
82+
public Dictionary<string, AttributeValue> Marshall_Enum() => _enum.Marshall();
83+
84+
[Benchmark]
85+
public Container<double> Unmarshall_Double() => _double.Unmarshall();
86+
87+
[Benchmark]
88+
public Dictionary<string, AttributeValue> Marshall_Double() => _double.Marshall();
89+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using Amazon.DynamoDBv2.Model;
2+
using BenchmarkDotNet.Attributes;
3+
using DynamoDBGenerator.Attributes;
4+
5+
namespace DynamoDBGenerator.SourceGenerator.Benchmarks.Benchmarks.Marshalling;
6+
7+
[DynamoDBMarshaller(EntityType = typeof(Container<DateTime>), AccessName = "DateTimeMarshaller")]
8+
[DynamoDBMarshaller(EntityType = typeof(Container<DateTimeOffset>), AccessName = "DateTimeOffsetMarshaller")]
9+
[DynamoDBMarshaller(EntityType = typeof(Container<DateOnly>), AccessName = "DateOnlyMarshaller")]
10+
[DynamoDBMarshaller(EntityType = typeof(Container<TimeOnly>), AccessName = "TimeOnlyMarshaller")]
11+
public partial class TemporalBenchmarks
12+
{
13+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<DateTime>, Container<DateTime>, ContainerDateTimeNames, ContainerDateTimeValues> _dateTime = DateTimeMarshaller.ToBenchmarkHelper();
14+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<DateTimeOffset>, Container<DateTimeOffset>, ContainerDateTimeOffsetNames, ContainerDateTimeOffsetValues> _dateTimeOffset = DateTimeOffsetMarshaller.ToBenchmarkHelper();
15+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<DateOnly>, Container<DateOnly>, ContainerDateOnlyNames, ContainerDateOnlyValues> _dateOnly = DateOnlyMarshaller.ToBenchmarkHelper();
16+
private readonly DynamoDbMarshallerBenchmarkHelper<Container<TimeOnly>, Container<TimeOnly>, ContainerTimeOnlyNames, ContainerTimeOnlyValues> _timeOnly = TimeOnlyMarshaller.ToBenchmarkHelper();
17+
18+
[Benchmark]
19+
public Container<TimeOnly> Unmarshall_TimeOnly() => _timeOnly.Unmarshall();
20+
21+
[Benchmark]
22+
public Dictionary<string, AttributeValue> Marshall_TimeOnly() => _timeOnly.Marshall();
23+
24+
[Benchmark]
25+
public Container<DateOnly> Unmarshall_DateOnly() => _dateOnly.Unmarshall();
26+
27+
[Benchmark]
28+
public Dictionary<string, AttributeValue> Marshall_DateOnly() => _dateOnly.Marshall();
29+
30+
[Benchmark]
31+
public Container<DateTimeOffset> Unmarshall_DateTimeOffset() => _dateTimeOffset.Unmarshall();
32+
33+
[Benchmark]
34+
public Dictionary<string, AttributeValue> Marshall_DateTimeOffset() => _dateTimeOffset.Marshall();
35+
36+
[Benchmark]
37+
public Container<DateTime> Unmarshall_DateTime() => _dateTime.Unmarshall();
38+
39+
[Benchmark]
40+
public Dictionary<string, AttributeValue> Marshall_DateTime() => _dateTime.Marshall();
41+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Amazon;
2+
using Amazon.DynamoDBv2;
3+
using Amazon.DynamoDBv2.DataModel;
4+
using Amazon.DynamoDBv2.DocumentModel;
5+
using Amazon.DynamoDBv2.Model;
6+
using BenchmarkDotNet.Attributes;
7+
8+
namespace DynamoDBGenerator.SourceGenerator.Benchmarks.Benchmarks;
9+
10+
//public abstract class SG_VS_AWS_Benchmarker<T>(
11+
// Func<T, Dictionary<string, AttributeValue>> marshaller,
12+
// Func<Dictionary<string, AttributeValue>, T> unMarshaller
13+
//)
14+
//{
15+
// private readonly DynamoDBContext _context = new DynamoDBContextBuilder()
16+
// .WithDynamoDBClient(() => new AmazonDynamoDBClient(RegionEndpoint.EUWest1))
17+
// .Build();
18+
//
19+
// private readonly ToDocumentConfig _dynamoDbOperationConfig = new() { Conversion = DynamoDBEntryConversion.V2 };
20+
//
21+
//
22+
// [Benchmark]
23+
// public Dictionary<string, AttributeValue> Marshall_AWS_Reflection() => _context
24+
// .ToDocument(SingleElement, _dynamoDbOperationConfig)
25+
// .ToAttributeMap(_dynamoDbOperationConfig.Conversion);
26+
//
27+
// [Benchmark]
28+
// public T Unmarshall_AWS_Reflection() => _context.FromDocument<T>(Document.FromAttributeMap(AttributeValues));
29+
//}

0 commit comments

Comments
 (0)