Files
Umbraco-CMS/tests/Umbraco.Tests.Benchmarks/ConcurrentDictionaryBenchmarks.cs

97 lines
3.2 KiB
C#
Raw Permalink Normal View History

2018-03-27 16:42:52 +02:00
using System;
using System.Collections.Concurrent;
using BenchmarkDotNet.Attributes;
using Umbraco.Cms.Core.Collections;
2018-03-27 16:42:52 +02:00
namespace Umbraco.Tests.Benchmarks;
[MemoryDiagnoser]
public class ConcurrentDictionaryBenchmarks
2018-03-27 16:42:52 +02:00
{
private static readonly ConcurrentDictionary<CompositeTypeTypeKey, bool> AssignableTypeCache = new();
2018-03-27 16:42:52 +02:00
private static readonly object input = new Bar();
2018-03-27 16:42:52 +02:00
private static readonly Type source = typeof(Bar);
2018-03-27 16:42:52 +02:00
private static readonly Type target = typeof(Foo);
2018-03-27 16:42:52 +02:00
[Benchmark(Baseline = true)]
public bool GetCachedCanAssignFactory() =>
AssignableTypeCache.GetOrAdd(new CompositeTypeTypeKey(source, target), k =>
2018-03-27 16:42:52 +02:00
{
var ksource = k.Type1;
var ktarget = k.Type2;
2018-03-27 16:42:52 +02:00
return ktarget.IsAssignableFrom(ksource) && typeof(IConvertible).IsAssignableFrom(ksource);
});
2018-03-27 16:42:52 +02:00
[Benchmark]
public bool GetCachedCanAssignNoFactory()
{
// This method is 10% faster
var key = new CompositeTypeTypeKey(source, target);
if (AssignableTypeCache.TryGetValue(key, out bool canConvert))
2018-03-27 16:42:52 +02:00
{
return canConvert;
2018-03-27 16:42:52 +02:00
}
// "is" is faster than "IsAssignableFrom"
if (input is IConvertible && target.IsAssignableFrom(source))
2018-03-27 16:42:52 +02:00
{
return AssignableTypeCache[key] = true;
}
2018-03-27 16:42:52 +02:00
return AssignableTypeCache[key] = false;
}
2018-03-27 16:42:52 +02:00
private class Foo : IConvertible
{
public TypeCode GetTypeCode() => TypeCode.Object;
2018-03-27 16:42:52 +02:00
public bool ToBoolean(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public byte ToByte(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public char ToChar(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public DateTime ToDateTime(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public decimal ToDecimal(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public double ToDouble(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public short ToInt16(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public int ToInt32(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public long ToInt64(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public sbyte ToSByte(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public float ToSingle(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public string ToString(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public object ToType(Type conversionType, IFormatProvider provider)
{
if (conversionType == typeof(Foo))
2018-03-27 16:42:52 +02:00
{
return new Foo();
2018-03-27 16:42:52 +02:00
}
throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
}
public ushort ToUInt16(IFormatProvider provider) => throw new NotImplementedException();
2018-03-27 16:42:52 +02:00
public uint ToUInt32(IFormatProvider provider) => throw new NotImplementedException();
public ulong ToUInt64(IFormatProvider provider) => throw new NotImplementedException();
}
private class Bar : Foo
{
2018-03-27 16:42:52 +02:00
}
}