Free cookie consent management tool by TermsFeed Policy Generator

Changeset 6205


Ignore:
Timestamp:
05/17/11 00:09:59 (12 years ago)
Author:
cneumuel
Message:

#1522

  • simplified check for EventHandler (by simply checking for delegate)
  • special handling types which use a hashtable internally (dictionaries, hashset, hashtable, ...) (as discussed with swagner)
  • added testcase which shows a stack overflow if ThreadLocal is included and compiler is on Debug (it does not happen in Release)
Location:
trunk/sources
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Common/3.3/ObjectExtensions.cs

    r6201 r6205  
    2121
    2222using System;
     23using System.Collections;
    2324using System.Collections.Generic;
     25using System.Collections.Specialized;
    2426using System.Reflection;
    25 using System.Collections;
     27using System.Threading;
    2628
    2729namespace HeuristicLab.Common {
     
    3537    /// Types not collected:
    3638    ///   * System.Delegate
    37     ///   * System.EventHandler (+ System.EventHandler<T>)
     39    ///   * System.Reflection.Pointer
    3840    ///   * Primitives (Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, Single)
    3941    ///   * string, decimal
    40     ///   * Arrays of primitives (+ string, decimal)
    41     /// Types of which the fields are not further collected:
    42     ///   * System.Type
    43     ///   * System.Threading.ThreadLocal<T>
     42    ///   * Arrays of types not collected
     43    ///  
     44    /// Dictionaries and HashSets are treated specially, because it is cheaper to iterate over their keys and values
     45    /// compared to traverse their internal data structures.
    4446    /// </summary>
    4547    private static void CollectObjectGraphObjects(this object obj, HashSet<object> objects) {
    4648      if (obj == null || objects.Contains(obj)) return;
    47       if (obj is Delegate || obj is EventHandler) return;
    48       if (obj is Pointer) return;
    4949      Type type = obj.GetType();
    50       if (type.IsSubclassOfRawGeneric(typeof(EventHandler<>))) return;
    51       if (type.IsPrimitive || type == typeof(string) || type == typeof(decimal)) return;
    52       if (type.HasElementType) {
    53         Type elementType = type.GetElementType();
    54         if (elementType.IsPrimitive || elementType == typeof(string) || elementType == typeof(decimal)) return;
    55         //TODO check all types
    56       }
     50      if (ExcludeType(type)) return;
     51      if (type.HasElementType && ExcludeType(type.GetElementType())) return;
    5752
    5853      objects.Add(obj);
    5954
    60       //if (typeof(Type).IsInstanceOfType(obj)) return; // avoid infinite recursion
    61       //if (type.IsSubclassOfRawGeneric(typeof(ThreadLocal<>))) return; // avoid stack overflow when the field `ConcurrentStack<int> s_availableIndices` grows large
    62 
    63       // performance critical to handle dictionaries in a special way
    64       var dictionary = obj as IDictionary;
    65       if (dictionary != null) {
     55      if (type.IsSubclassOfRawGeneric(typeof(ThreadLocal<>))) return; // avoid stack overflow when the field `ConcurrentStack<int> s_availableIndices` too grows large
     56     
     57      // performance critical to handle dictionaries, hashsets and hashtables in a special way
     58      if (type.IsSubclassOfRawGeneric(typeof(Dictionary<,>)) ||
     59          type.IsSubclassOfRawGeneric(typeof(SortedDictionary<,>)) ||
     60          type.IsSubclassOfRawGeneric(typeof(SortedList<,>)) ||
     61          obj is SortedList ||
     62          obj is OrderedDictionary ||
     63          obj is ListDictionary ||
     64          obj is Hashtable) {       
     65        var dictionary = obj as IDictionary;
    6666        foreach (object value in dictionary.Keys)
    6767          CollectObjectGraphObjects(value, objects);
     
    6969          CollectObjectGraphObjects(value, objects);
    7070        return;
    71       } else if (type.IsArray) {
    72         var array = obj as Array;
    73         foreach (object value in array)
     71      } else if (type.IsArray || type.IsSubclassOfRawGeneric(typeof(HashSet<>))) {
     72        var enumerable = obj as IEnumerable;
     73        foreach (var value in enumerable)
    7474          CollectObjectGraphObjects(value, objects);
    7575        return;
     
    8080      }
    8181    }
     82
     83    private static bool ExcludeType(Type type) {
     84      return type.IsPrimitive ||
     85             type == typeof(string) ||
     86             type == typeof(decimal) ||
     87             typeof(Delegate).IsAssignableFrom(type) ||
     88             typeof(Pointer).IsAssignableFrom(type);
     89    }
    8290  }
    8391}
  • trunk/sources/HeuristicLab/3.3/Tests/CollectObjectGraphTest.cs

    r6201 r6205  
    2424using System.Diagnostics;
    2525using System.Linq;
     26using System.Threading;
    2627using HeuristicLab.Algorithms.GeneticAlgorithm;
    2728using HeuristicLab.Common;
     29using HeuristicLab.Optimization;
    2830using HeuristicLab.Persistence.Default.Xml;
     31using HeuristicLab.Problems.TestFunctions;
     32using HeuristicLab.Random;
     33using HeuristicLab.SequentialEngine;
    2934using Microsoft.VisualStudio.TestTools.UnitTesting;
    3035
     
    8287      TestContext.WriteLine("");
    8388    }
     89
     90    [TestMethod]
     91    public void AlgorithmExecutions() {
     92      var random = new MersenneTwister(0);
     93      var algs = new List<IAlgorithm>();
     94
     95      Stopwatch sw = new Stopwatch();
     96      for (int i = 0; i < 100; i++) {
     97        GeneticAlgorithm ga = new GeneticAlgorithm();
     98        ga.PopulationSize.Value = 5;
     99        ga.MaximumGenerations.Value = 5;
     100        ga.Engine = new SequentialEngine();
     101        ga.Problem = new SingleObjectiveTestFunctionProblem();
     102
     103        sw.Start();
     104        algs.Add(ga);
     105
     106        var cancellationTokenSource = new CancellationTokenSource();
     107        ga.StartSync(cancellationTokenSource.Token);
     108        sw.Stop();
     109        TestContext.WriteLine("{0}: {1} ", i, sw.Elapsed);
     110        sw.Reset();
     111      }
     112    }
    84113  }
    85114}
  • trunk/sources/HeuristicLab/3.3/Tests/HeuristicLab-3.3.Tests.csproj

    r6201 r6205  
    122122  </ItemGroup>
    123123  <ItemGroup>
     124    <Compile Include="AlgorithmExtensions.cs" />
    124125    <Compile Include="CloningConstructorTest.cs" />
    125126    <Compile Include="CollectObjectGraphTest.cs" />
     
    559560      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    560561    </None>
     562    <None Include="GA_SymbReg2.hl">
     563      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     564    </None>
    561565  </ItemGroup>
    562566  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
Note: See TracChangeset for help on using the changeset viewer.