Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
06/09/10 16:29:02 (14 years ago)
Author:
epitzer
Message:

Accelerate persistence: (#646)

  • dynamically compile field and property accessors
  • enable caching of compiled field and property accessors
  • delay costly custom attribute retrieval by checking signatures first
  • implement custom List<double> serializer
  • log deserialization time span
Location:
trunk/sources/HeuristicLab.Persistence/3.3/Default
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableReflection.cs

    r3742 r3913  
    7373
    7474    private static object[] emptyArgs = new object[0];
     75    private static Type[] objectArg = new[] { typeof(object) };
    7576
    7677    public static IEnumerable<Hook> CollectHooks(HookType hookType, Type type) {
     
    7980          yield return mi;
    8081      foreach (MemberInfo memberInfo in type.GetMembers(DECLARED_INSTANCE_MEMBERS)) {
     82        if (memberInfo.MemberType != MemberTypes.Method)
     83          continue;
     84        MethodInfo methodInfo = memberInfo as MethodInfo;
     85        if (methodInfo.ReturnType != typeof(void))
     86          continue;
     87        if (methodInfo.GetParameters().Length > 0)
     88          continue;
    8189        foreach (StorableHookAttribute hook in memberInfo.GetCustomAttributes(typeof(StorableHookAttribute), false)) {
    8290          if (hook != null && hook.HookType == hookType) {
    83             MethodInfo methodInfo = memberInfo as MethodInfo;
    84             if (memberInfo.MemberType != MemberTypes.Method || memberInfo == null)
    85               throw new ArgumentException("Storable hooks must be methods");           
    86             DynamicMethod dm = new DynamicMethod("", null, new[] { typeof(object) }, type);
    87             ILGenerator ilgen = dm.GetILGenerator();
    88             ilgen.Emit(OpCodes.Ldarg_0);
    89             ilgen.Emit(OpCodes.Callvirt, methodInfo);
    90             ilgen.Emit(OpCodes.Ret);
    91             yield return (Hook)dm.CreateDelegate(typeof(Hook));           
     91            yield return new Hook((o) => methodInfo.Invoke(o, emptyArgs));
    9292          }
    9393        }
     
    9999    private static void AddMarkedMembers(Type type, List<StorableMemberInfo> storableMembers) {
    100100      foreach (MemberInfo memberInfo in type.GetMembers(DECLARED_INSTANCE_MEMBERS)) {
    101         foreach (StorableAttribute attribute in memberInfo.GetCustomAttributes(typeof(StorableAttribute), false)) {
    102           storableMembers.Add(new StorableMemberInfo(attribute, memberInfo));
     101        if (memberInfo.MemberType == MemberTypes.Field ||
     102          memberInfo.MemberType == MemberTypes.Property) {
     103          foreach (StorableAttribute attribute in memberInfo.GetCustomAttributes(typeof(StorableAttribute), false)) {
     104            storableMembers.Add(new StorableMemberInfo(attribute, memberInfo));
     105          }
    103106        }
    104107      }
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs

    r3742 r3913  
    109109    /// <returns>An enumerable of <see cref="Tag"/>s.</returns>
    110110    public IEnumerable<Tag> Decompose(object obj) {
    111       foreach (var accessor in GetStorableAccessors(obj)) {
    112         yield return new Tag(accessor.Name, accessor.Get());
     111      foreach (var accessor in GetStorableAccessors(obj.GetType())) {
     112        yield return new Tag(accessor.Name, accessor.Get(obj));
    113113      }
    114114    }
     
    142142        memberDict.Add(iter.Current.Name, iter.Current);
    143143      }
    144       foreach (var accessor in GetStorableAccessors(instance)) {
     144      foreach (var accessor in GetStorableAccessors(instance.GetType())) {
    145145        if (memberDict.ContainsKey(accessor.Name)) {
    146           accessor.Set(memberDict[accessor.Name].Value);
     146          accessor.Set(instance, memberDict[accessor.Name].Value);
    147147        } else if (accessor.DefaultValue != null) {
    148           accessor.Set(accessor.DefaultValue);
     148          accessor.Set(instance, accessor.DefaultValue);
    149149        }
    150150      }
     
    160160
    161161    private static readonly object[] emptyArgs = new object[] { };
     162    private static readonly object[] trueArgs = new object[] { true };
    162163
    163164    private sealed class HookDesignator {
     
    171172    }
    172173
    173     private sealed class MemberCache : Dictionary<Type, IEnumerable<StorableMemberInfo>> { }
     174    private sealed class AccessorListCache : Dictionary<Type, IEnumerable<DataMemberAccessor>> { }
     175    private sealed class AccessorCache : Dictionary<MemberInfo, DataMemberAccessor> { }
    174176
    175177    #endregion
     
    177179    #region caches
    178180
    179     private MemberCache storableMemberCache = new MemberCache();
     181    private AccessorListCache accessorListCache = new AccessorListCache();
     182    private AccessorCache accessorCache = new AccessorCache();
    180183
    181184    private delegate object Constructor();
     
    191194    #region attribute access
    192195
    193     private IEnumerable<StorableMemberInfo> GetStorableMembers(Type type) {
    194       lock (storableMemberCache) {
    195         if (storableMemberCache.ContainsKey(type))
    196           return storableMemberCache[type];
    197         var storablesMembers = StorableReflection.GenerateStorableMembers(type);
    198         storableMemberCache[type] = storablesMembers;
    199         return storablesMembers;
     196    private IEnumerable<DataMemberAccessor> GetStorableAccessors(Type type) {
     197      lock (accessorListCache) {
     198        if (accessorListCache.ContainsKey(type))
     199          return accessorListCache[type];
     200        var storableMembers = StorableReflection
     201          .GenerateStorableMembers(type)
     202          .Select(mi => GetMemberAccessor(mi));
     203        accessorListCache[type] = storableMembers;
     204        return storableMembers;
     205      }     
     206    }
     207
     208    private DataMemberAccessor GetMemberAccessor(StorableMemberInfo mi) {
     209      lock (accessorCache) {
     210        if (accessorCache.ContainsKey(mi.MemberInfo))
     211          return new DataMemberAccessor(accessorCache[mi.MemberInfo], mi.DisentangledName, mi.DefaultValue);
     212        DataMemberAccessor dma = new DataMemberAccessor(mi.MemberInfo, mi.DisentangledName, mi.DefaultValue);
     213        accessorCache[mi.MemberInfo] = dma;
     214        return dma;
    200215      }
    201216    }
     
    209224        return c;
    210225      }
    211     }
     226    }   
    212227
    213228    private Constructor GetDefaultConstructor(Type type) {
    214229      ConstructorInfo ci = type.GetConstructor(ALL_CONSTRUCTORS, null, Type.EmptyTypes, null);
    215230      if (ci == null)
    216         return null;
     231        return null;     
    217232      DynamicMethod dm = new DynamicMethod("", typeof(object), null, type);
    218233      ILGenerator ilgen = dm.GetILGenerator();
     
    227242          if (ci.GetParameters().Length != 1 ||
    228243              ci.GetParameters()[0].ParameterType != typeof(bool))
    229             throw new PersistenceException("StorableConstructor must have exactly one argument of type bool");
     244            throw new PersistenceException("StorableConstructor must have exactly one argument of type bool");         
    230245          DynamicMethod dm = new DynamicMethod("", typeof(object), null, type);
    231246          ILGenerator ilgen = dm.GetILGenerator();
     
    237252      }
    238253      return null;
    239     }
    240 
    241     private IEnumerable<DataMemberAccessor> GetStorableAccessors(object obj) {
    242       return GetStorableMembers(obj.GetType())
    243         .Select(mi => new DataMemberAccessor(mi.MemberInfo, mi.DisentangledName, mi.DefaultValue, obj));
    244     }
     254    }   
    245255
    246256    private void InvokeHook(HookType hookType, object obj) {
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/DoubleList2XmlSerializer.cs

    r3742 r3913  
    2323using System.Collections.Generic;
    2424using System;
     25using System.Linq;
    2526using HeuristicLab.Persistence.Core;
    2627using HeuristicLab.Persistence.Default.Xml.Primitive;
     28using System.Text;
    2729
    2830namespace HeuristicLab.Persistence.Default.Xml.Compact {
    2931
    30   internal sealed class DoubleList2XmlSerializer : NumberEnumeration2XmlSerializerBase<List<double>> {
     32  internal sealed class DoubleList2XmlSerializer : CompactXmlSerializerBase<List<double>> {
    3133
    32     protected override void Add(IEnumerable enumeration, object o) {
    33       ((List<double>)enumeration).Add((double)o);
     34    private static readonly char[] separators = new char[] { ';' };
     35
     36    public override XmlString Format(List<double> list) {
     37      StringBuilder sb = new StringBuilder();
     38      foreach (var d in list) {
     39        sb.Append(Double2XmlSerializer.FormatG17(d)).Append(';');
     40      }
     41      return new XmlString(sb.ToString());
    3442    }
    3543
    36     protected override IEnumerable Instantiate() {
    37       return new List<double>();
     44    public override List<double> Parse(XmlString data) {
     45      try {
     46        var values = data.Data.Split(separators, StringSplitOptions.RemoveEmptyEntries);
     47        List<double> list = new List<double>(values.Length);
     48        foreach (var value in values) {
     49          list.Add(Double2XmlSerializer.ParseG17(value));
     50        }
     51        return list;
     52      } catch (InvalidCastException e) {
     53        throw new PersistenceException("Invalid element data during reconstruction of List<double>.", e);
     54      } catch (OverflowException e) {
     55        throw new PersistenceException("Overflow during element parsing while trying to reconstruct List<double>.", e);
     56      }
    3857    }
    39 
    40     protected override string FormatValue(object o) {
    41       return Double2XmlSerializer.FormatG17((double)o);
    42     }
    43 
    44     protected override object ParseValue(string o) {
    45       return Double2XmlSerializer.ParseG17(o);
    46     }
    47 
    4858  }
    4959}
  • trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlParser.cs

    r3742 r3913  
    188188    /// <returns>A fresh object instance</returns>
    189189    public static object Deserialize(string filename) {
    190       using (ZipFile file = new ZipFile(filename)) {
    191         return Deserialize(file);
     190      TimeSpan start = System.Diagnostics.Process.GetCurrentProcess().TotalProcessorTime;
     191      try {
     192        using (ZipFile file = new ZipFile(filename)) {
     193          return Deserialize(file);
     194        }
     195      } finally {
     196        TimeSpan end = System.Diagnostics.Process.GetCurrentProcess().TotalProcessorTime;
     197        Tracing.Logger.Info(string.Format(
     198          "deserialization of {0} took {1} seconds",
     199          filename, (end - start).TotalSeconds));
    192200      }
    193201    }
Note: See TracChangeset for help on using the changeset viewer.