Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
06/09/10 16:29:02 (15 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/CompositeSerializers/Storable
Files:
2 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) {
Note: See TracChangeset for help on using the changeset viewer.