diff --git a/Mutators/AutoEvaluators/NullifyIfConfiguration.cs b/Mutators/AutoEvaluators/NullifyIfConfiguration.cs index 27cb2243..1b7f59ad 100644 --- a/Mutators/AutoEvaluators/NullifyIfConfiguration.cs +++ b/Mutators/AutoEvaluators/NullifyIfConfiguration.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; @@ -59,12 +59,13 @@ public override Expression Apply(Expression path, List GetMerger(MutatorsContext context) public MutatorsTreeBase Migrate(MutatorsTreeBase mutatorsTree, MutatorsContext context) { - return mutatorsTree == null ? null : mutatorsTree.Migrate(GetOrCreateHashtableSlot(context).ConverterTree); + return mutatorsTree?.Migrate(GetOrCreateHashtableSlot(context).ConverterTree); } public MutatorsTreeBase GetValidationsTree(MutatorsContext context, int priority) @@ -71,7 +71,7 @@ public MutatorsTreeBase GetValidationsTree(MutatorsContext context, int public MutatorsTreeBase MigratePaths(MutatorsTreeBase mutatorsTree, MutatorsContext context) { - return mutatorsTree == null ? null : mutatorsTree.MigratePaths(GetOrCreateHashtableSlot(context).ConverterTree); + return mutatorsTree?.MigratePaths(GetOrCreateHashtableSlot(context).ConverterTree); } protected abstract void Configure(MutatorsContext context, ConverterConfigurator configurator); @@ -103,28 +103,39 @@ private HashtableSlot GetOrCreateHashtableSlot(MutatorsContext context) ConfigureInternal(context, new ConverterConfigurator(tree)); var validationsTree = ModelConfigurationNode.CreateRoot(typeof(TSource)); tree.ExtractValidationsFromConverters(validationsTree); - var treeMutator = (Expression>)tree.BuildTreeMutator(typeof(TSource)); - logger.Info($"Started compiling converter from {typeof(TSource).FullName} to {typeof(TDest).FullName} with context: {key}"); - var compiledTreeMutator = LambdaCompiler.Compile(treeMutator, CompilerOptions.All); - logger.Info($"Finished compiling converter from {typeof(TSource).FullName} to {typeof(TDest).FullName}"); + + var treeConverter = (Expression>)tree.BuildTreeMutator(typeof(TSource)); + + Action compiledTreeConverter; + var sw = Stopwatch.StartNew(); + try + { + compiledTreeConverter = LambdaCompiler.Compile(treeConverter, CompilerOptions.All); + } + finally + { + sw.Stop(); + LogConverterCompilation(context, sw); + } + slot = new HashtableSlot { ConverterTree = tree, ValidationsTree = validationsTree, - Converter = (source => + Converter = source => { var dest = new TDest(); BeforeConvert(source); - compiledTreeMutator(dest, source); + compiledTreeConverter(dest, source); AfterConvert(dest, source); return dest; - }), - Merger = ((source, dest) => + }, + Merger = (source, dest) => { BeforeConvert(source); - compiledTreeMutator(dest, source); + compiledTreeConverter(dest, source); AfterConvert(dest, source); - }), + }, ValidationMutatorsTrees = new Hashtable() }; //if(!MutatorsAssignRecorder.IsRecording()) @@ -136,33 +147,17 @@ private HashtableSlot GetOrCreateHashtableSlot(MutatorsContext context) return slot; } - private HashtableSlot CreateHashtableSlot(MutatorsContext context) + private void LogConverterCompilation(MutatorsContext context, Stopwatch sw) { - var converterTree = ModelConfigurationNode.CreateRoot(typeof(TDest)); - ConfigureInternal(context, new ConverterConfigurator(converterTree)); - var validationsTree = ModelConfigurationNode.CreateRoot(typeof(TSource)); - converterTree.ExtractValidationsFromConverters(validationsTree); - var treeMutator = (Expression>)converterTree.BuildTreeMutator(typeof(TSource)); - var compiledTreeMutator = LambdaCompiler.Compile(treeMutator, CompilerOptions.All); - return new HashtableSlot + var logProperties = new Dictionary { - ConverterTree = converterTree, - ValidationsTree = validationsTree, - Converter = source => - { - var dest = new TDest(); - BeforeConvert(source); - compiledTreeMutator(dest, source); - AfterConvert(dest, source); - return dest; - }, - Merger = (source, dest) => - { - BeforeConvert(source); - compiledTreeMutator(dest, source); - AfterConvert(dest, source); - } + {"ConverterCollectionName", GetType().Name}, + {"CompilationTimeMilliseconds", sw.ElapsedMilliseconds} }; + var mutatorsContextTypeName = context.GetType().Name; + foreach (var propertyInfo in context.GetType().GetProperties()) + logProperties.Add($"{mutatorsContextTypeName}.{propertyInfo.Name}", propertyInfo.GetValue(context)); + logger.Log(new LogEvent(LogLevel.Info, DateTimeOffset.UtcNow, "{ConverterCollectionName} was compiled in {CompilationTimeMilliseconds} ms", logProperties)); } private static TypeCode GetTypeCode(Type type) @@ -421,13 +416,6 @@ private Expression MakeConvert(Expression value, Type type) return Expression.Convert(value, type); } - private static bool IsPrimitive(Type type) - { - if (type.IsNullable()) - return IsPrimitive(type.GetGenericArguments()[0]); - return type.IsPrimitive || type == typeof(decimal); - } - private void ConfigureCustomFields(ConverterConfigurator configurator) { var sourceParameter = Expression.Parameter(typeof(TSource)); @@ -472,8 +460,7 @@ private void ConfigureCustomFieldsForArrays(ConverterConfigurator configurator) + protected void ConfigureInternal(MutatorsContext context, ConverterConfigurator configurator) { Configure(context, configurator); ConfigureCustomFields(configurator); diff --git a/Mutators/MutatorsContext.cs b/Mutators/MutatorsContext.cs index da489c6e..95f3cf16 100644 --- a/Mutators/MutatorsContext.cs +++ b/Mutators/MutatorsContext.cs @@ -1,8 +1,9 @@ -namespace GrobExp.Mutators +namespace GrobExp.Mutators { public abstract class MutatorsContext { public abstract string GetKey(); + public static readonly MutatorsContext Empty = new EmptyMutatorsContext(); } @@ -10,7 +11,7 @@ public sealed class EmptyMutatorsContext : MutatorsContext { public override string GetKey() { - return ""; + return string.Empty; } } } \ No newline at end of file diff --git a/Mutators/MutatorsTreeBase.cs b/Mutators/MutatorsTreeBase.cs index 36dd35c0..4d3afdd8 100644 --- a/Mutators/MutatorsTreeBase.cs +++ b/Mutators/MutatorsTreeBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Linq;