Created
November 2, 2017 02:50
-
-
Save SergeyTeplyakov/6b6c118650204b7f085b7b4ae41cd848 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TypeTuple : IEquatable<TypeTuple> | |
{ | |
public bool Equals(TypeTuple other) | |
{ | |
if (ReferenceEquals(null, other)) return false; | |
return EqualityComparer<Type>.Default.Equals(this.Source, other.Source) && | |
EqualityComparer<Type>.Default.Equals(this.Destination, other.Destination); | |
} | |
public override bool Equals(object obj) | |
{ | |
return Equals(obj as TypeTuple); | |
} | |
public override int GetHashCode() | |
{ | |
unchecked | |
{ | |
return ((Source?.GetHashCode() ?? 0) << 16) ^ ((Destination?.GetHashCode() ?? 0) & 65535); | |
} | |
} | |
public static bool operator ==(TypeTuple left, TypeTuple right) | |
{ | |
if (ReferenceEquals(null, left)) return ReferenceEquals(null, right); | |
return left.Equals(right); | |
} | |
public static bool operator !=(TypeTuple left, TypeTuple right) | |
{ | |
if (ReferenceEquals(null, left)) return !ReferenceEquals(null, right); | |
return !left.Equals(right); | |
} | |
public Type Source { get; } | |
public Type Destination { get; } | |
public TypeTuple(Type source, Type destination) | |
{ | |
this.Source = source; | |
this.Destination = destination; | |
} | |
} | |
public class TypeTuple2<T1, T2> : IEquatable<TypeTuple2<T1, T2>> | |
{ | |
public bool Equals(TypeTuple2<T1, T2> other) | |
{ | |
if (ReferenceEquals(null, other)) return false; | |
return EqualityComparer<T1>.Default.Equals(this.Source, other.Source) && | |
EqualityComparer<T2>.Default.Equals(this.Destination, other.Destination); | |
} | |
public override bool Equals(object obj) | |
{ | |
return Equals(obj as TypeTuple2<T1, T2>); | |
} | |
public override int GetHashCode() | |
{ | |
unchecked | |
{ | |
return ((Source?.GetHashCode() ?? 0) << 16) ^ ((Destination?.GetHashCode() ?? 0) & 65535); | |
} | |
} | |
public static bool operator ==(TypeTuple2<T1, T2> left, TypeTuple2<T1, T2> right) | |
{ | |
if (ReferenceEquals(null, left)) return ReferenceEquals(null, right); | |
return left.Equals(right); | |
} | |
public static bool operator !=(TypeTuple2<T1, T2> left, TypeTuple2<T1, T2> right) | |
{ | |
if (ReferenceEquals(null, left)) return !ReferenceEquals(null, right); | |
return !left.Equals(right); | |
} | |
public T1 Source { get; } | |
public T2 Destination { get; } | |
public TypeTuple2(T1 source, T2 destination) | |
{ | |
this.Source = source; | |
this.Destination = destination; | |
} | |
} | |
public class StructTypeTuple : IEquatable<StructTypeTuple> | |
{ | |
public bool Equals(StructTypeTuple other) | |
{ | |
if (ReferenceEquals(null, other)) return false; | |
return Source == other.Source && Destination == other.Destination; | |
} | |
public override bool Equals(object obj) | |
{ | |
return Equals(obj as StructTypeTuple); | |
} | |
public override int GetHashCode() | |
{ | |
unchecked | |
{ | |
return ((Source?.GetHashCode() ?? 0) << 16) ^ ((Destination?.GetHashCode() ?? 0) & 65535); | |
} | |
} | |
public static bool operator ==(StructTypeTuple left, StructTypeTuple right) | |
{ | |
if (ReferenceEquals(null, left)) return ReferenceEquals(null, right); | |
return left.Equals(right); | |
} | |
public static bool operator !=(StructTypeTuple left, StructTypeTuple right) | |
{ | |
if (ReferenceEquals(null, left)) return !ReferenceEquals(null, right); | |
return !left.Equals(right); | |
} | |
public Type Source { get; } | |
public Type Destination { get; } | |
public StructTypeTuple(Type source, Type destination) | |
{ | |
this.Source = source; | |
this.Destination = destination; | |
} | |
} | |
class CustomerDto | |
{ | |
} | |
class Customer | |
{ | |
} | |
[MemoryDiagnoser] | |
public class DelegateStorageRetrieve | |
{ | |
private Dictionary<(Type, Type), Delegate> dictTupleStorage = new Dictionary<(Type, Type), Delegate>(); | |
private Dictionary<TypeTuple, Delegate> dictTypeTupleStorage = new Dictionary<TypeTuple, Delegate>(); | |
private Dictionary<TypeTuple2<Type, Type>, Delegate> genDictTypeTupleStorage = new Dictionary<TypeTuple2<Type, Type>, Delegate>(); | |
private Dictionary<System.Tuple<Type, Type>, Delegate> regularDictTypeTupleStorage = new Dictionary<System.Tuple<Type, Type>, Delegate>(); | |
private Dictionary<StructTypeTuple, Delegate> dictStructTypeTupleStorage = new Dictionary<StructTypeTuple, Delegate>(); | |
[GlobalSetup] | |
public void Init() | |
{ | |
Func<CustomerDto, Customer> activator = (x) => new Customer(); | |
dictTupleStorage.Add((typeof(CustomerDto), typeof(Customer)), activator); | |
dictTypeTupleStorage.Add(new TypeTuple(typeof(CustomerDto), typeof(Customer)), activator); | |
genDictTypeTupleStorage.Add(new TypeTuple2<Type, Type>(typeof(CustomerDto), typeof(Customer)), activator); | |
dictStructTypeTupleStorage.Add(new StructTypeTuple(typeof(CustomerDto), typeof(Customer)), activator); | |
regularDictTypeTupleStorage.Add(new Tuple<Type, Type>(typeof(CustomerDto), typeof(Customer)), activator); | |
} | |
[Benchmark] | |
public Delegate DictionaryTuple() | |
{ | |
var key = (typeof(CustomerDto), typeof(Customer)); | |
return dictTupleStorage[key]; | |
} | |
[Benchmark] | |
public Delegate DictionaryTypeTuple() | |
{ | |
var key = new TypeTuple(typeof(CustomerDto), typeof(Customer)); | |
return dictTypeTupleStorage[key]; | |
} | |
[Benchmark] | |
public Delegate DictionaryGenericTypeTuple() | |
{ | |
var key = new TypeTuple2<Type, Type>(typeof(CustomerDto), typeof(Customer)); | |
return genDictTypeTupleStorage[key]; | |
} | |
[Benchmark] | |
public Delegate DictionaryStructTypeTuple() | |
{ | |
var key = new StructTypeTuple(typeof(CustomerDto), typeof(Customer)); | |
return dictStructTypeTupleStorage[key]; | |
} | |
[Benchmark] | |
public Delegate DictionarySystemTuple() | |
{ | |
var key = new Tuple<Type, Type>(typeof(CustomerDto), typeof(Customer)); | |
return regularDictTypeTupleStorage[key]; | |
} | |
} | |
// Results | |
/* | |
Method | Mean | Error | StdDev | Gen 0 | Allocated | | |
--------------------------- |----------:|----------:|----------:|-------:|----------:| | |
DictionaryTuple | 101.18 ns | 0.4298 ns | 0.3810 ns | - | 0 B | | |
DictionaryTypeTuple | 72.63 ns | 0.2599 ns | 0.2304 ns | 0.0101 | 32 B | | |
DictionaryGenericTypeTuple | 99.30 ns | 1.7590 ns | 1.6454 ns | 0.0101 | 32 B | | |
DictionaryStructTypeTuple | 48.71 ns | 0.1830 ns | 0.1429 ns | 0.0101 | 32 B | | |
DictionarySystemTuple | 132.99 ns | 0.4867 ns | 0.3800 ns | 0.0100 | 32 B | | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment