Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableReflection.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableReflection.cs	(revision 3811)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableReflection.cs	(revision 3913)
@@ -73,4 +73,5 @@
 
     private static object[] emptyArgs = new object[0];
+    private static Type[] objectArg = new[] { typeof(object) };
 
     public static IEnumerable<Hook> CollectHooks(HookType hookType, Type type) {
@@ -79,15 +80,14 @@
           yield return mi;
       foreach (MemberInfo memberInfo in type.GetMembers(DECLARED_INSTANCE_MEMBERS)) {
+        if (memberInfo.MemberType != MemberTypes.Method)
+          continue;
+        MethodInfo methodInfo = memberInfo as MethodInfo;
+        if (methodInfo.ReturnType != typeof(void))
+          continue;
+        if (methodInfo.GetParameters().Length > 0)
+          continue;
         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");            
-            DynamicMethod dm = new DynamicMethod("", null, new[] { typeof(object) }, type);
-            ILGenerator ilgen = dm.GetILGenerator();
-            ilgen.Emit(OpCodes.Ldarg_0);
-            ilgen.Emit(OpCodes.Callvirt, methodInfo);
-            ilgen.Emit(OpCodes.Ret);
-            yield return (Hook)dm.CreateDelegate(typeof(Hook));            
+            yield return new Hook((o) => methodInfo.Invoke(o, emptyArgs));
           }
         }
@@ -99,6 +99,9 @@
     private static void AddMarkedMembers(Type type, List<StorableMemberInfo> storableMembers) {
       foreach (MemberInfo memberInfo in type.GetMembers(DECLARED_INSTANCE_MEMBERS)) {
-        foreach (StorableAttribute attribute in memberInfo.GetCustomAttributes(typeof(StorableAttribute), false)) {
-          storableMembers.Add(new StorableMemberInfo(attribute, memberInfo));
+        if (memberInfo.MemberType == MemberTypes.Field ||
+          memberInfo.MemberType == MemberTypes.Property) {
+          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/StorableSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs	(revision 3811)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/Storable/StorableSerializer.cs	(revision 3913)
@@ -109,6 +109,6 @@
     /// <returns>An enumerable of <see cref="Tag"/>s.</returns>
     public IEnumerable<Tag> Decompose(object obj) {
-      foreach (var accessor in GetStorableAccessors(obj)) {
-        yield return new Tag(accessor.Name, accessor.Get());
+      foreach (var accessor in GetStorableAccessors(obj.GetType())) {
+        yield return new Tag(accessor.Name, accessor.Get(obj));
       }
     }
@@ -142,9 +142,9 @@
         memberDict.Add(iter.Current.Name, iter.Current);
       }
-      foreach (var accessor in GetStorableAccessors(instance)) {
+      foreach (var accessor in GetStorableAccessors(instance.GetType())) {
         if (memberDict.ContainsKey(accessor.Name)) {
-          accessor.Set(memberDict[accessor.Name].Value);
+          accessor.Set(instance, memberDict[accessor.Name].Value);
         } else if (accessor.DefaultValue != null) {
-          accessor.Set(accessor.DefaultValue);
+          accessor.Set(instance, accessor.DefaultValue);
         }
       }
@@ -160,4 +160,5 @@
 
     private static readonly object[] emptyArgs = new object[] { };
+    private static readonly object[] trueArgs = new object[] { true };
 
     private sealed class HookDesignator {
@@ -171,5 +172,6 @@
     }
 
-    private sealed class MemberCache : Dictionary<Type, IEnumerable<StorableMemberInfo>> { }
+    private sealed class AccessorListCache : Dictionary<Type, IEnumerable<DataMemberAccessor>> { }
+    private sealed class AccessorCache : Dictionary<MemberInfo, DataMemberAccessor> { }
 
     #endregion
@@ -177,5 +179,6 @@
     #region caches
 
-    private MemberCache storableMemberCache = new MemberCache();
+    private AccessorListCache accessorListCache = new AccessorListCache();
+    private AccessorCache accessorCache = new AccessorCache();
 
     private delegate object Constructor();
@@ -191,11 +194,23 @@
     #region attribute access
 
-    private IEnumerable<StorableMemberInfo> GetStorableMembers(Type type) {
-      lock (storableMemberCache) {
-        if (storableMemberCache.ContainsKey(type))
-          return storableMemberCache[type];
-        var storablesMembers = StorableReflection.GenerateStorableMembers(type);
-        storableMemberCache[type] = storablesMembers;
-        return storablesMembers;
+    private IEnumerable<DataMemberAccessor> GetStorableAccessors(Type type) {
+      lock (accessorListCache) {
+        if (accessorListCache.ContainsKey(type))
+          return accessorListCache[type];
+        var storableMembers = StorableReflection
+          .GenerateStorableMembers(type)
+          .Select(mi => GetMemberAccessor(mi));
+        accessorListCache[type] = storableMembers;
+        return storableMembers;
+      }      
+    }
+
+    private DataMemberAccessor GetMemberAccessor(StorableMemberInfo mi) {
+      lock (accessorCache) {
+        if (accessorCache.ContainsKey(mi.MemberInfo))
+          return new DataMemberAccessor(accessorCache[mi.MemberInfo], mi.DisentangledName, mi.DefaultValue);
+        DataMemberAccessor dma = new DataMemberAccessor(mi.MemberInfo, mi.DisentangledName, mi.DefaultValue);
+        accessorCache[mi.MemberInfo] = dma;
+        return dma;
       }
     }
@@ -209,10 +224,10 @@
         return c;
       }
-    }
+    }    
 
     private Constructor GetDefaultConstructor(Type type) {
       ConstructorInfo ci = type.GetConstructor(ALL_CONSTRUCTORS, null, Type.EmptyTypes, null);
       if (ci == null)
-        return null;
+        return null;      
       DynamicMethod dm = new DynamicMethod("", typeof(object), null, type);
       ILGenerator ilgen = dm.GetILGenerator();
@@ -227,5 +242,5 @@
           if (ci.GetParameters().Length != 1 ||
               ci.GetParameters()[0].ParameterType != typeof(bool))
-            throw new PersistenceException("StorableConstructor must have exactly one argument of type bool");
+            throw new PersistenceException("StorableConstructor must have exactly one argument of type bool");          
           DynamicMethod dm = new DynamicMethod("", typeof(object), null, type);
           ILGenerator ilgen = dm.GetILGenerator();
@@ -237,10 +252,5 @@
       }
       return null;
-    }
-
-    private IEnumerable<DataMemberAccessor> GetStorableAccessors(object obj) {
-      return GetStorableMembers(obj.GetType())
-        .Select(mi => new DataMemberAccessor(mi.MemberInfo, mi.DisentangledName, mi.DefaultValue, obj));
-    }
+    }    
 
     private void InvokeHook(HookType hookType, object obj) {
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/DoubleList2XmlSerializer.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/DoubleList2XmlSerializer.cs	(revision 3811)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/Compact/DoubleList2XmlSerializer.cs	(revision 3913)
@@ -23,27 +23,37 @@
 using System.Collections.Generic;
 using System;
+using System.Linq;
 using HeuristicLab.Persistence.Core;
 using HeuristicLab.Persistence.Default.Xml.Primitive;
+using System.Text;
 
 namespace HeuristicLab.Persistence.Default.Xml.Compact {
 
-  internal sealed class DoubleList2XmlSerializer : NumberEnumeration2XmlSerializerBase<List<double>> {
+  internal sealed class DoubleList2XmlSerializer : CompactXmlSerializerBase<List<double>> {
 
-    protected override void Add(IEnumerable enumeration, object o) {
-      ((List<double>)enumeration).Add((double)o);
+    private static readonly char[] separators = new char[] { ';' };
+
+    public override XmlString Format(List<double> list) {
+      StringBuilder sb = new StringBuilder();
+      foreach (var d in list) {
+        sb.Append(Double2XmlSerializer.FormatG17(d)).Append(';');
+      }
+      return new XmlString(sb.ToString());
     }
 
-    protected override IEnumerable Instantiate() {
-      return new List<double>();
+    public override List<double> Parse(XmlString data) {
+      try {
+        var values = data.Data.Split(separators, StringSplitOptions.RemoveEmptyEntries);
+        List<double> list = new List<double>(values.Length);
+        foreach (var value in values) {
+          list.Add(Double2XmlSerializer.ParseG17(value));
+        }
+        return list;
+      } catch (InvalidCastException e) {
+        throw new PersistenceException("Invalid element data during reconstruction of List<double>.", e);
+      } catch (OverflowException e) {
+        throw new PersistenceException("Overflow during element parsing while trying to reconstruct List<double>.", e);
+      }
     }
-
-    protected override string FormatValue(object o) {
-      return Double2XmlSerializer.FormatG17((double)o);
-    }
-
-    protected override object ParseValue(string o) {
-      return Double2XmlSerializer.ParseG17(o);
-    }
-
   }
 }
Index: trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlParser.cs
===================================================================
--- trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlParser.cs	(revision 3811)
+++ trunk/sources/HeuristicLab.Persistence/3.3/Default/Xml/XmlParser.cs	(revision 3913)
@@ -188,6 +188,14 @@
     /// <returns>A fresh object instance</returns>
     public static object Deserialize(string filename) {
-      using (ZipFile file = new ZipFile(filename)) {
-        return Deserialize(file);
+      TimeSpan start = System.Diagnostics.Process.GetCurrentProcess().TotalProcessorTime;
+      try {
+        using (ZipFile file = new ZipFile(filename)) {
+          return Deserialize(file);
+        }
+      } finally {
+        TimeSpan end = System.Diagnostics.Process.GetCurrentProcess().TotalProcessorTime;
+        Tracing.Logger.Info(string.Format(
+          "deserialization of {0} took {1} seconds",
+          filename, (end - start).TotalSeconds));
       }
     }
