Skip to content

Instantly share code, notes, and snippets.

@madelson
Created April 8, 2022 19:33
Show Gist options
  • Save madelson/a00d163d6aa3b6add4f01f206f4fbde2 to your computer and use it in GitHub Desktop.
Save madelson/a00d163d6aa3b6add4f01f206f4fbde2 to your computer and use it in GitHub Desktop.
#if NET
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.Extensions.Configuration.Binder.Tests
{
public class ConfigurationBinderAllocationsBenchmark
{
[Fact]
public void BenchmarkAllocations()
{
var parameters = new (double ScalarFillFactor, int CollectionSize)[]
{
(0.5, 2),
(0.5, 20),
(1, 2),
(1, 20),
};
foreach (var parameter in parameters)
{
IConfiguration config = BuildConfiguration(parameter.ScalarFillFactor, parameter.CollectionSize);
// warm up
config.Get<BenchmarkOptions>();
long beforeBytes = GC.GetAllocatedBytesForCurrentThread();
config.Get<BenchmarkOptions>();
long allocatedBytes = GC.GetAllocatedBytesForCurrentThread() - beforeBytes;
Console.WriteLine($"{parameter} -> {allocatedBytes}");
}
var options = BuildConfiguration(1, 1).Get<BenchmarkOptions>();
Assert.Equal(4, options.I5);
Assert.Equal(1000, options.O1.I1);
Assert.Equal("text", options.L1[0].S1);
Assert.Equal(System.Text.RegularExpressions.RegexOptions.IgnoreCase, options.D1["0"].E1);
}
private static IConfiguration BuildConfiguration(double scalarFillFactor, int collectionSize)
{
var data = new Dictionary<string, string>();
for (var i = 0; i < 12 * scalarFillFactor; i++)
{
data.Add($"B{i + 1}", (i % 2 == 0).ToString());
}
for (var i = 0; i < 6 * scalarFillFactor; i++)
{
data.Add($"I{i + 1}", i.ToString());
}
AddSubOptions("O1:");
for (var i = 0; i < collectionSize; i++)
{
AddSubOptions($"L1:{i}:");
AddSubOptions($"D1:{i}:");
}
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddInMemoryCollection(data);
return configurationBuilder.Build();
void AddSubOptions(string prefix)
{
data.Add(prefix + "B1", "true");
data.Add(prefix + "I1", "1000");
data.Add(prefix + "E1", "IgnoreCase");
data.Add(prefix + "S1", "text");
for (var i = 0; i < collectionSize; i++)
{
data.Add(prefix + "A1:" + i, i.ToString());
}
}
}
private class BenchmarkOptions
{
public bool B1 { get; set; }
public bool B2 { get; set; }
public bool B3 { get; set; }
public bool B4 { get; set; }
public bool B5 { get; set; }
public bool B6 { get; set; }
public bool B7 { get; set; }
public bool B8 { get; set; }
public bool B9 { get; set; }
public bool B10 { get; set; }
public bool B11 { get; set; }
public bool B12 { get; set; }
public int I1 { get; set; }
public int? I2 { get; set; }
public int? I3 { get; set; }
public int I4 { get; set; }
public int I5 { get; set; }
public int I6 { get; set; }
public BenchmarkSubOptions O1 { get; } = new BenchmarkSubOptions();
public IDictionary<string, BenchmarkSubOptions> D1 { get; } = new Dictionary<string, BenchmarkSubOptions>();
public IList<BenchmarkSubOptions> L1 { get; } = new List<BenchmarkSubOptions>();
}
private class BenchmarkSubOptions
{
public bool? B1 { get; set; }
public int? I1 { get; set; }
public System.Text.RegularExpressions.RegexOptions? E1 { get; set; }
public string? S1 { get; set; }
public string[]? A1 { get; set; }
}
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment