Skip to content

Instantly share code, notes, and snippets.

@SergeyTeplyakov
Created November 2, 2017 02:50
Show Gist options
  • Save SergeyTeplyakov/6b6c118650204b7f085b7b4ae41cd848 to your computer and use it in GitHub Desktop.
Save SergeyTeplyakov/6b6c118650204b7f085b7b4ae41cd848 to your computer and use it in GitHub Desktop.
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