Method | Mean | Error | StdDev |
---|---|---|---|
Dictionary | 18.28 ns | 3.178 ns | 0.1742 ns |
DictionaryWithLock | 31.25 ns | 39.024 ns | 2.1390 ns |
ThreadsafeHashArray | 21.99 ns | 4.916 ns | 0.2694 ns |
SimpleMetadataFactory | 16.85 ns | 2.537 ns | 0.1391 ns |
PolicyMetadataFactory | 17.56 ns | 1.543 ns | 0.0846 ns |
Last active
February 20, 2019 06:20
-
-
Save usausa/5a89726a065c919bf6a9f6cfccb17493 to your computer and use it in GitHub Desktop.
Static field in generic type with policy
This file contains hidden or 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
using System; | |
public interface IPolicy | |
{ | |
string ToName(string source); | |
} | |
public sealed class DefaultPolicy : IPolicy | |
{ | |
public string ToName(string source) => source; | |
} | |
public sealed class LowerPolicy : IPolicy | |
{ | |
public string ToName(string source) => source.ToLower(); | |
} | |
public abstract class SeparatorPolicy : IPolicy | |
{ | |
public sealed class PathPolicy : SeparatorPolicy | |
{ | |
public PathPolicy() : base(true, "\\") | |
{ | |
} | |
} | |
public sealed class UnderlinePolicy : SeparatorPolicy | |
{ | |
public UnderlinePolicy() : base(false, "_") | |
{ | |
} | |
} | |
private readonly bool root; | |
private readonly string separator; | |
private SeparatorPolicy(bool root, string separator) | |
{ | |
this.root = root; | |
this.separator = separator; | |
} | |
public string ToName(string source) => (root ? separator : "") + source.Replace(".", separator); | |
} | |
public class Metadata | |
{ | |
public string Name { get; } | |
public Metadata(string name) | |
{ | |
Name = name; | |
} | |
} | |
public interface IMetadataFactory | |
{ | |
Metadata Create<T>(); | |
} | |
public sealed class StandardMetadataFactory<TPolicy> : IMetadataFactory | |
where TPolicy : IPolicy | |
{ | |
private static readonly IPolicy Policy = (IPolicy)Activator.CreateInstance(typeof(TPolicy)); | |
private static class MetadataHolder<T> | |
{ | |
public static Metadata Value { get; } | |
static MetadataHolder() | |
{ | |
Value = new Metadata(Policy.ToName(typeof(T).FullName)); | |
} | |
} | |
public Metadata Create<T>() | |
{ | |
return MetadataHolder<T>.Value; | |
} | |
} | |
public static class MetadataFactories | |
{ | |
public static IMetadataFactory Default { get; } = new StandardMetadataFactory<DefaultPolicy>(); | |
public static IMetadataFactory Lower { get; } = new StandardMetadataFactory<LowerPolicy>(); | |
public static IMetadataFactory Path { get; } = new StandardMetadataFactory<SeparatorPolicy. PathPolicy>(); | |
public static IMetadataFactory Underline { get; } = new StandardMetadataFactory<SeparatorPolicy.UnderlinePolicy>(); | |
} | |
public class Component | |
{ | |
public IMetadataFactory MetadataFactory { get; set; } = MetadataFactories.Default; | |
public void ShowName<T>() | |
{ | |
Console.WriteLine(MetadataFactory.Create<T>().Name); | |
} | |
} | |
public static class Program | |
{ | |
public static void Main() | |
{ | |
var component = new Component(); | |
// System.String | |
component.ShowName<string>(); | |
// system.string | |
component.MetadataFactory = MetadataFactories.Lower; | |
component.ShowName<string>(); | |
// \System\String | |
component.MetadataFactory = MetadataFactories.Path; | |
component.ShowName<string>(); | |
// System_String | |
component.MetadataFactory = MetadataFactories.Underline; | |
component.ShowName<string>(); | |
} | |
} |
This file contains hidden or 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
using System; | |
using System.Collections.Generic; | |
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Configs; | |
using BenchmarkDotNet.Diagnosers; | |
using BenchmarkDotNet.Exporters; | |
using BenchmarkDotNet.Jobs; | |
using BenchmarkDotNet.Running; | |
using Smart.Collections.Concurrent; | |
public static class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
BenchmarkRunner.Run<Benchmark>(); | |
} | |
} | |
public class BenchmarkConfig : ManualConfig | |
{ | |
public BenchmarkConfig() | |
{ | |
Add(MarkdownExporter.Default, MarkdownExporter.GitHub); | |
Add(MemoryDiagnoser.Default); | |
Add(Job.ShortRun); | |
} | |
} | |
[Config(typeof(BenchmarkConfig))] | |
public class Benchmark | |
{ | |
private static readonly Type TypeKey = typeof(object); | |
private readonly Func<Type, string> factory = x => x.FullName; | |
private readonly Dictionary<Type, string> dictionary = new Dictionary<Type, string>(); | |
private readonly ThreadsafeTypeHashArrayMap<string> hashArrayMap = new ThreadsafeTypeHashArrayMap<string>(); | |
private readonly IMetadataFactory simpleMetadataFactory = new SimpleMetadataFactory(); | |
private readonly IMetadataFactory policyMetadataFactory = new PolicyMetadataFactory<DefaultPolicy>(); | |
[GlobalSetup] | |
public void Setup() | |
{ | |
dictionary[TypeKey] = TypeKey.ToString(); | |
hashArrayMap.AddIfNotExist(TypeKey, TypeKey.ToString()); | |
simpleMetadataFactory.Create<object>(); | |
policyMetadataFactory.Create<object>(); | |
} | |
[Benchmark] | |
public string Dictionary() | |
{ | |
if (!dictionary.TryGetValue(TypeKey, out var name)) | |
{ | |
name = TypeKey.ToString(); | |
dictionary[TypeKey] = name; | |
} | |
return name; | |
} | |
[Benchmark] | |
public string DictionaryWithLock() | |
{ | |
lock (dictionary) | |
{ | |
if (!dictionary.TryGetValue(TypeKey, out var name)) | |
{ | |
name = TypeKey.ToString(); | |
dictionary[TypeKey] = name; | |
} | |
return name; | |
} | |
} | |
[Benchmark] | |
public string ThreadsafeHashArray() | |
{ | |
return hashArrayMap.AddIfNotExist(TypeKey, factory); | |
} | |
[Benchmark] | |
public string SimpleMetadataFactory() | |
{ | |
return simpleMetadataFactory.Create<object>(); | |
} | |
[Benchmark] | |
public string PolicyMetadataFactory() | |
{ | |
return policyMetadataFactory.Create<object>(); | |
} | |
} | |
public interface IMetadataFactory | |
{ | |
string Create<T>(); | |
} | |
public sealed class SimpleMetadataFactory : IMetadataFactory | |
{ | |
private static class MetadataHolder<T> | |
{ | |
public static string Value { get; } | |
static MetadataHolder() | |
{ | |
Value = typeof(T).FullName; | |
} | |
} | |
public string Create<T>() | |
{ | |
return MetadataHolder<T>.Value; | |
} | |
} | |
public interface IPolicy | |
{ | |
string ToName(string source); | |
} | |
public sealed class DefaultPolicy : IPolicy | |
{ | |
public string ToName(string source) => source; | |
} | |
public sealed class PolicyMetadataFactory<TPolicy> : IMetadataFactory | |
where TPolicy : IPolicy | |
{ | |
private static readonly IPolicy Policy = (IPolicy)Activator.CreateInstance(typeof(TPolicy)); | |
private static class MetadataHolder<T> | |
{ | |
public static string Value { get; } | |
static MetadataHolder() | |
{ | |
Value = Policy.ToName(typeof(T).FullName); | |
} | |
} | |
public string Create<T>() | |
{ | |
return MetadataHolder<T>.Value; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment