From dd3a1949665081be889bcd4b91e72bdc86bf9867 Mon Sep 17 00:00:00 2001 From: bollhals Date: Tue, 20 Apr 2021 01:12:20 +0200 Subject: [PATCH 1/2] improve RegistrationKey performance - add IEquatable - cache typeGroup --- BoDi/BoDi.cs | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/BoDi/BoDi.cs b/BoDi/BoDi.cs index fcdd880..690b1b4 100644 --- a/BoDi/BoDi.cs +++ b/BoDi/BoDi.cs @@ -291,29 +291,19 @@ public override string ToString() } } - private struct RegistrationKey + private readonly struct RegistrationKey : IEquatable { public readonly Type Type; + private readonly Type typeGroup; public readonly string Name; public RegistrationKey(Type type, string name) { - if (type == null) throw new ArgumentNullException("type"); - - Type = type; + Type = type ?? throw new ArgumentNullException(nameof(type)); + typeGroup = (type.IsGenericType && !type.IsGenericTypeDefinition) ? type.GetGenericTypeDefinition() : type; Name = name; } - private Type TypeGroup - { - get - { - if (Type.IsGenericType && !Type.IsGenericTypeDefinition) - return Type.GetGenericTypeDefinition(); - return Type; - } - } - public override string ToString() { Debug.Assert(Type.FullName != null); @@ -323,10 +313,10 @@ public override string ToString() return string.Format("{0}('{1}')", Type.FullName, Name); } - bool Equals(RegistrationKey other) + public bool Equals(RegistrationKey other) { - var isInvertable = other.TypeGroup == Type || other.Type == TypeGroup || other.Type == Type; - return isInvertable && String.Equals(other.Name, Name, StringComparison.CurrentCultureIgnoreCase); + var isInvertable = other.Type == Type || other.typeGroup == Type || other.Type == typeGroup; + return isInvertable && other.Name == Name; } public override bool Equals(object obj) @@ -338,10 +328,7 @@ public override bool Equals(object obj) public override int GetHashCode() { - unchecked - { - return TypeGroup.GetHashCode(); - } + return typeGroup.GetHashCode(); } } From 35598b7cc87554e1c39c88d57bbf24cd29c6faab Mon Sep 17 00:00:00 2001 From: bollhals Date: Wed, 21 Apr 2021 00:24:28 +0200 Subject: [PATCH 2/2] add ResolveFromGenericType benchmark --- .../Benchmarks/ResolveFromGenericType.cs | 25 +++++++++++++++++++ .../SingleContainerBenchmarkBase.cs | 15 ++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 BoDi.Performance.Tests/Benchmarks/ResolveFromGenericType.cs diff --git a/BoDi.Performance.Tests/Benchmarks/ResolveFromGenericType.cs b/BoDi.Performance.Tests/Benchmarks/ResolveFromGenericType.cs new file mode 100644 index 0000000..ddd7876 --- /dev/null +++ b/BoDi.Performance.Tests/Benchmarks/ResolveFromGenericType.cs @@ -0,0 +1,25 @@ +using BenchmarkDotNet.Attributes; + +namespace BODi.Performance.Tests.Benchmarks +{ + public class ResolveFromGenericType : SingleContainerBenchmarkBase + { + [Benchmark(Baseline = true, Description = "v1.4")] + public object Version_1_4() + { + return Container14.Resolve>(); + } + + [Benchmark(Description = "v1.BoDi_Concurrent_Dictionary_And_Lazy")] + public object Version_1_BoDi_Concurrent_Dictionary_And_Lazy() + { + return Container1Concurrent_Dictionary_And_Lazy.Resolve>(); + } + + [Benchmark(Description = "Current")] + public object CurrentVersion() + { + return ContainerCurrent.Resolve>(); + } + } +} \ No newline at end of file diff --git a/BoDi.Performance.Tests/Benchmarks/SingleContainerBenchmarkBase.cs b/BoDi.Performance.Tests/Benchmarks/SingleContainerBenchmarkBase.cs index 9195b0a..e26868e 100644 --- a/BoDi.Performance.Tests/Benchmarks/SingleContainerBenchmarkBase.cs +++ b/BoDi.Performance.Tests/Benchmarks/SingleContainerBenchmarkBase.cs @@ -6,19 +6,21 @@ namespace BODi.Performance.Tests.Benchmarks { [HtmlExporter] [MarkdownExporterAttribute.GitHub] + [MemoryDiagnoser] [MinColumn, MaxColumn, MeanColumn, MedianColumn, RankColumn] [Orderer(SummaryOrderPolicy.FastestToSlowest, MethodOrderPolicy.Declared)] public abstract class SingleContainerBenchmarkBase { - protected internal IObjectContainer ContainerCurrent; - protected internal BoDi1_4.IObjectContainer Container14; - protected internal BoDi_Concurrent_Dictionary_And_Lazy.IObjectContainer Container1Concurrent_Dictionary_And_Lazy; + protected internal ObjectContainer ContainerCurrent; + protected internal BoDi1_4.ObjectContainer Container14; + protected internal BoDi_Concurrent_Dictionary_And_Lazy.ObjectContainer Container1Concurrent_Dictionary_And_Lazy; [GlobalSetup] public void Setup() { Container14 = new BoDi1_4.ObjectContainer(); Container14.RegisterFactoryAs(_ => new FactoryRegistered()); + Container14.RegisterTypeAs(typeof(GenericRegistered<>), typeof(IGenericRegistered<>)); Container14.RegisterTypeAs(); Container14.RegisterTypeAs(); Container14.RegisterTypeAs(); @@ -32,6 +34,7 @@ public void Setup() Container1Concurrent_Dictionary_And_Lazy = new BoDi_Concurrent_Dictionary_And_Lazy.ObjectContainer(); Container1Concurrent_Dictionary_And_Lazy.RegisterFactoryAs(_ => new FactoryRegistered()); + Container1Concurrent_Dictionary_And_Lazy.RegisterTypeAs(typeof(GenericRegistered<>), typeof(IGenericRegistered<>)); Container1Concurrent_Dictionary_And_Lazy.RegisterTypeAs(); Container1Concurrent_Dictionary_And_Lazy.RegisterTypeAs(); Container1Concurrent_Dictionary_And_Lazy.RegisterTypeAs(); @@ -44,6 +47,7 @@ public void Setup() ContainerCurrent = new ObjectContainer(); ContainerCurrent.RegisterFactoryAs(_ => new FactoryRegistered()); + ContainerCurrent.RegisterTypeAs(typeof(GenericRegistered<>), typeof(IGenericRegistered<>)); ContainerCurrent.RegisterTypeAs(); ContainerCurrent.RegisterTypeAs(); ContainerCurrent.RegisterTypeAs(); @@ -53,9 +57,12 @@ public void Setup() ContainerCurrent.RegisterFactoryAs(_ => new AllRegistered2()); ContainerCurrent.RegisterFactoryAs(_ => new AllRegistered3()); ContainerCurrent.RegisterFactoryAs(_ => new AllRegistered4()); - } + protected internal interface IGenericRegistered { } + + protected internal class GenericRegistered : IGenericRegistered { } + protected internal class FactoryRegistered { } protected internal class TypeRegistered { }