Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableAttribute.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableAttribute.cs	(revision 2990)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableAttribute.cs	(revision 2991)
@@ -88,10 +88,12 @@
 
     public static IEnumerable<StorableMemberInfo> GetStorableMembers(Type type, bool inherited) {
-      var query = new TypeQuery(type, inherited);
-      if (memberCache.ContainsKey(query))
-        return memberCache[query];
-      var storablesMembers = GenerateStorableMembers(type, inherited);
-      memberCache[query] = storablesMembers;
-      return storablesMembers;
+      lock (memberCache) {
+        var query = new TypeQuery(type, inherited);
+        if (memberCache.ContainsKey(query))
+          return memberCache[query];
+        var storablesMembers = GenerateStorableMembers(type, inherited);
+        memberCache[query] = storablesMembers;
+        return storablesMembers;
+      }
     }
 
@@ -101,9 +103,6 @@
         storableMembers.AddRange(GenerateStorableMembers(type.BaseType, true));
       foreach (MemberInfo memberInfo in type.GetMembers(instanceMembers)) {
-        foreach (object attribute in memberInfo.GetCustomAttributes(false)) {
-          StorableAttribute storableAttribute = attribute as StorableAttribute;
-          if (storableAttribute != null) {
-            storableMembers.Add(new StorableMemberInfo(storableAttribute, memberInfo));
-          }
+        foreach (StorableAttribute attribute in memberInfo.GetCustomAttributes(typeof(StorableAttribute), false)) {          
+          storableMembers.Add(new StorableMemberInfo(attribute, memberInfo));          
         }
       }
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableConstructorAttribute.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableConstructorAttribute.cs	(revision 2990)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableConstructorAttribute.cs	(revision 2991)
@@ -12,21 +12,26 @@
 
     private static readonly BindingFlags allConstructors =
-      BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
+      BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;    
 
-    private static readonly object[] defaultArgs = new object[] { true };
+    private static Dictionary<Type, ConstructorInfo> constructorCache =
+      new Dictionary<Type, ConstructorInfo>();
 
-    public static object CallStorableConstructor(Type type) {
-      foreach (ConstructorInfo constructorInfo in type.GetConstructors(allConstructors)) {
-        if (constructorInfo
-          .GetCustomAttributes(typeof(StorableConstructorAttribute), false).Length > 0) {
-          if (constructorInfo.GetParameters().Length != 1 ||
-              constructorInfo.GetParameters()[0].ParameterType != typeof(bool))
-            throw new PersistenceException("StorableConstructor must have exactly one argument of type bool");
-          return constructorInfo.Invoke(defaultArgs);
+    public static ConstructorInfo GetStorableConstructor(Type type) {
+      lock (constructorCache) {
+        if (constructorCache.ContainsKey(type))
+          return constructorCache[type];
+        foreach (ConstructorInfo ci in type.GetConstructors(allConstructors)) {
+          if (ci.GetCustomAttributes(typeof(StorableConstructorAttribute), false).Length > 0) {
+            if (ci.GetParameters().Length != 1 ||
+                ci.GetParameters()[0].ParameterType != typeof(bool))
+              throw new PersistenceException("StorableConstructor must have exactly one argument of type bool");
+            constructorCache[type] = ci;
+            return ci;
+          }
         }
+        constructorCache[type] = null;
+        return null;
       }
-      return null;
     }
-
   }
 }
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableHookAttribute.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableHookAttribute.cs	(revision 2990)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableHookAttribute.cs	(revision 2991)
@@ -11,4 +11,14 @@
   [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
   public sealed class StorableHookAttribute : Attribute {
+
+    private sealed class HookDesignator {
+      public Type Type { get; set; }
+      public HookType HookType { get; set; }
+      public HookDesignator() { }
+      public HookDesignator(Type type, HookType hookType) {
+        Type = type;
+        HookType = HookType;
+      }
+    }
 
     private readonly HookType hookType;
@@ -26,15 +36,36 @@
     private static readonly object[] emptyArgs = new object[] { };
 
+    private static Dictionary<HookDesignator, List<MethodInfo>> hookCache =
+      new Dictionary<HookDesignator, List<MethodInfo>>();
+
     public static void InvokeHook(HookType hookType, object obj) {
       if (obj == null)
         throw new ArgumentNullException("Cannot invoke hooks on null");
-      Type type = obj.GetType();
+      foreach (MethodInfo mi in GetHooks(hookType, obj.GetType())) {
+        mi.Invoke(obj, emptyArgs);
+      }
+    }
+
+    private static IEnumerable<MethodInfo> GetHooks(HookType hookType, Type type) {
+      lock (hookCache) {
+        List<MethodInfo> hooks;
+        var designator = new HookDesignator(type, hookType);
+        hookCache.TryGetValue(designator, out hooks);
+        if (hooks != null)
+          return hooks;
+        hooks = new List<MethodInfo>(CollectHooks(hookType, type));
+        hookCache.Add(designator, hooks);
+        return hooks;
+      }
+    }
+
+    private static IEnumerable<MethodInfo> CollectHooks(HookType hookType, Type type) {      
       foreach (MemberInfo memberInfo in type.GetMembers(instanceMembers)) {
-        foreach (StorableHookAttribute hook in memberInfo.GetCustomAttributes(typeof(StorableHookAttribute), false)) {          
+        foreach (StorableHookAttribute hook in memberInfo.GetCustomAttributes(typeof(StorableHookAttribute), false)) {
           if (hook != null && hook.HookType == hookType) {
             MethodInfo methodInfo = memberInfo as MethodInfo;
             if (memberInfo.MemberType != MemberTypes.Method || memberInfo == null)
               throw new ArgumentException("Storable hooks must be methods");
-            methodInfo.Invoke(obj, emptyArgs);
+            yield return methodInfo;
           }
         }
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs	(revision 2990)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs	(revision 2991)
@@ -19,5 +19,5 @@
       if (!ReflectionTools.HasDefaultConstructor(type))
         return false;
-      while (type != null) {        
+      while (type != null) {
         if (StorableAttribute.GetStorableMembers(type, false).Count() == 0 &&
             !EmptyStorableClassAttribute.IsEmptyStorable(type))
@@ -39,10 +39,10 @@
     }
 
+    private static readonly object[] defaultArgs = new object[] { true };
+
     public object CreateInstance(Type type, IEnumerable<Tag> metaInfo) {
       try {
-        object instance = StorableConstructorAttribute.CallStorableConstructor(type);
-        if (instance == null)
-          instance = Activator.CreateInstance(type, true);
-        return instance;
+        ConstructorInfo constructor = StorableConstructorAttribute.GetStorableConstructor(type);
+        return constructor != null ? constructor.Invoke(defaultArgs) :  Activator.CreateInstance(type, true);        
       } catch (TargetInvocationException x) {
         throw new PersistenceException(
