Changeset 14315


Ignore:
Timestamp:
09/29/16 10:42:52 (5 years ago)
Author:
gkronber
Message:

#2653: using Lazy initialization pattern to remove explicit locking (happens within Lazy instead)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModelSurrogate.cs

    r14236 r14315  
    2121#endregion
    2222
     23using System;
    2324using System.Collections.Generic;
     25using System.Diagnostics.Eventing.Reader;
    2426using System.Linq;
    2527using HeuristicLab.Common;
     
    3638  public sealed class GradientBoostedTreesModelSurrogate : RegressionModel, IGradientBoostedTreesModel {
    3739    // don't store the actual model!
    38     private IGradientBoostedTreesModel actualModel; // the actual model is only recalculated when necessary
     40    // the actual model is only recalculated when necessary
     41    private readonly Lazy<IGradientBoostedTreesModel> actualModel;
     42    private IGradientBoostedTreesModel ActualModel {
     43      get { return actualModel.Value; }
     44    }
    3945
    4046    [Storable]
     
    5763
    5864    public override IEnumerable<string> VariablesUsedForPrediction {
    59       get
    60       {
    61         lock (actualModel) { if (actualModel == null) actualModel = RecalculateModel(); }
    62         return actualModel.Models.SelectMany(x => x.VariablesUsedForPrediction).Distinct().OrderBy(x => x);
     65      get {
     66        return ActualModel.Models.SelectMany(x => x.VariablesUsedForPrediction).Distinct().OrderBy(x => x);
    6367      }
    6468    }
    6569
    6670    [StorableConstructor]
    67     private GradientBoostedTreesModelSurrogate(bool deserializing) : base(deserializing) { }
     71    private GradientBoostedTreesModelSurrogate(bool deserializing)
     72      : base(deserializing) {
     73      actualModel = new Lazy<IGradientBoostedTreesModel>(() => RecalculateModel());
     74    }
    6875
    6976    private GradientBoostedTreesModelSurrogate(GradientBoostedTreesModelSurrogate original, Cloner cloner)
    7077      : base(original, cloner) {
    71       if (original.actualModel != null) this.actualModel = cloner.Clone(original.actualModel);
     78      IGradientBoostedTreesModel clonedModel = null;
     79      if (original.ActualModel != null) clonedModel = cloner.Clone(original.ActualModel);
     80      actualModel = new Lazy<IGradientBoostedTreesModel>(CreateLazyInitFunc(clonedModel)); // only capture clonedModel in the closure
    7281
    7382      this.trainingProblemData = cloner.Clone(original.trainingProblemData);
     
    7988      this.m = original.m;
    8089      this.nu = original.nu;
     90    }
     91
     92    private Func<IGradientBoostedTreesModel> CreateLazyInitFunc(IGradientBoostedTreesModel clonedModel) {
     93      return () => {
     94        return clonedModel == null ? RecalculateModel() : clonedModel;
     95      };
    8196    }
    8297
     
    100115      IGradientBoostedTreesModel model)
    101116      : this(trainingProblemData, seed, lossFunction, iterations, maxSize, r, m, nu) {
    102       this.actualModel = model;
     117      actualModel = new Lazy<IGradientBoostedTreesModel>(() => model);
    103118    }
    104119
     
    109124    // forward message to actual model (recalculate model first if necessary)
    110125    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
    111       lock (actualModel) { if (actualModel == null) actualModel = RecalculateModel(); }
    112       return actualModel.GetEstimatedValues(dataset, rows);
     126      return ActualModel.GetEstimatedValues(dataset, rows);
    113127    }
    114128
     
    123137    public IEnumerable<IRegressionModel> Models {
    124138      get {
    125         lock(actualModel) { if (actualModel == null) actualModel = RecalculateModel();}
    126         return actualModel.Models;
     139        return ActualModel.Models;
    127140      }
    128141    }
     
    130143    public IEnumerable<double> Weights {
    131144      get {
    132         lock(actualModel) { if (actualModel == null) actualModel = RecalculateModel();}
    133         return actualModel.Weights;
     145        return ActualModel.Weights;
    134146      }
    135147    }
Note: See TracChangeset for help on using the changeset viewer.