Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/11/17 20:07:13 (7 years ago)
Author:
pkimmesw
Message:

#2665 PooledPushProgram reduces memory usage and increases performance

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PushGP/HeuristicLab.PushGP/HeuristicLab.Problems.ProgramSynthesis/Push/Expressions/CodeExpressions.cs

    r14745 r14746  
    108108      var second = interpreter.CodeStack.Top;
    109109
    110       var isFirstList = first.CanExpand;
    111       var isSecondList = second.CanExpand;
    112 
    113       Expression[] result = null;
     110      var isFirstList = first.IsProgram;
     111      var isSecondList = second.IsProgram;
     112
     113      PushProgram result;
    114114
    115115      if (isFirstList) {
    116         var expand1 = first as PushProgram;
     116        var program1 = first as PushProgram;
    117117
    118118        if (isSecondList) {
    119           var expand2 = second as PushProgram;
    120           var size = expand2.State.Length + expand1.State.Length;
     119          var program2 = second as PushProgram;
     120          var size = program2.Expressions.Count + program1.Expressions.Count;
    121121
    122122          // if size > maxPointsInProgram this expressions results in a NOOP
    123123          if (size > interpreter.Configuration.MaxPointsInProgram) return false;
    124124
    125           result = new Expression[size];
    126 
    127           Array.Copy(expand2.State, result, expand2.State.Length);
    128           Array.Copy(
    129               expand1.State,
    130               0,
    131               result,
    132               expand2.State.Length,
    133               expand1.State.Length);
     125          result = PushProgram.Merge(interpreter.PushProgramPool, program2, program1);
    134126        } else {
    135           var size = expand1.State.Length + 1;
     127          var size = program1.Expressions.Count + 1;
    136128
    137129          // if size > maxPointsInProgram this expressions results in a NOOP
    138130          if (size > interpreter.Configuration.MaxPointsInProgram) return false;
    139131
    140           result = new Expression[size];
    141           result[0] = second;
    142 
    143           Array.Copy(expand1.State, 0, result, 1, expand1.State.Length);
     132          result = PushProgram.Merge(interpreter.PushProgramPool, second, program1);
    144133        }
    145134      } else if (isSecondList) {
    146         var expand2 = second as PushProgram;
    147 
    148         var size = expand2.State.Length + 1;
     135        var program2 = second as PushProgram;
     136        var size = program2.Expressions.Count + 1;
    149137
    150138        // if size > maxPointsInProgram this expressions results in a NOOP
    151139        if (size > interpreter.Configuration.MaxPointsInProgram) return false;
    152140
    153         result = new Expression[size];
    154         result[0] = first;
    155 
    156         Array.Copy(expand2.State as Expression[], 0, result, 1, expand2.State.Length);
     141        result = PushProgram.Merge(interpreter.PushProgramPool, first, program2);
    157142      } else {
    158         result = new[] { second, first };
     143        result = PushProgram.Create(interpreter.PushProgramPool, second, first);
    159144      }
    160145
    161       var expression = new PushProgram(result);
    162 
    163       interpreter.CodeStack.SetTop(expression);
     146      interpreter.CodeStack.SetTop(result);
    164147
    165148      return true;
     
    177160
    178161      var expression = interpreter.CodeStack.Pop();
    179       var isExpandExpression = expression.CanExpand;
     162      var isExpandExpression = expression.IsProgram;
    180163
    181164      interpreter.BooleanStack.Push(!isExpandExpression);
     
    199182
    200183      if (expand.IsEmpty) return false;
    201       var first = expand.State[expand.State.Length - 1];
     184      var first = expand.Expressions[expand.Expressions.Count - 1];
    202185
    203186      interpreter.CodeStack.SetTop(first);
     
    217200      if (interpreter.CodeStack.Count == 0) return false;
    218201
    219       PushProgram expandExpression;
     202      PushProgram result;
    220203      var top = interpreter.CodeStack.Top;
    221204
    222       if (top.CanExpand) {
    223         var expand = (PushProgram)top;
    224 
    225         if (expand.IsEmpty) return false;
    226         var length = expand.State.Length - 1;
    227         var newExpressions = new Expression[length];
    228 
    229         Array.Copy((Expression[])expand.State, 0, newExpressions, 0, length);
    230 
    231         expandExpression = new PushProgram(newExpressions);
     205      if (top.IsProgram) {
     206        var program = (PushProgram)top;
     207
     208        if (program.IsEmpty) return false;
     209
     210        result = program.Copy(interpreter.PushProgramPool, 0, program.Expressions.Count - 1);
    232211      } else {
    233         expandExpression = PushProgram.Empty;
     212        result = PushProgram.Empty;
    234213      }
    235214
    236       interpreter.CodeStack.SetTop(expandExpression);
     215      interpreter.CodeStack.SetTop(result);
    237216      return true;
    238217    }
     
    252231      PushProgram result;
    253232
    254       if (interpreter.CodeStack.Top.CanExpand) {
     233      if (interpreter.CodeStack.Top.IsProgram) {
    255234        var first = (PushProgram)interpreter.CodeStack.Pop();
    256         var size = first.State.Length + 1;
     235        var size = first.Expressions.Count + 1;
    257236
    258237        if (size > interpreter.Configuration.MaxPointsInProgram) return false;
     
    260239        var expressions = new Expression[size];
    261240
    262         expressions[first.State.Length] = interpreter.CodeStack.Top;
    263         Array.Copy(first.State as Expression[], expressions, first.State.Length);
    264 
    265         result = new PushProgram(expressions);
     241        first.CopyExpressionsTo(expressions);
     242        expressions[first.Expressions.Count] = interpreter.CodeStack.Top;
     243
     244        result = PushProgram.Create(interpreter.PushProgramPool, expressions);
    266245      } else {
    267         result = new PushProgram(interpreter.CodeStack.Pop(), interpreter.CodeStack.Top);
     246        result = PushProgram.Create(interpreter.PushProgramPool, interpreter.CodeStack.Top);
    268247      }
    269248
     
    303282
    304283      var subContainer =
    305           current.State.Where(e => e.CanExpand)
     284          current.Expressions.Where(e => e.IsProgram)
    306285              .Select(e => GetContainer(e as PushProgram, target))
    307286              .Where(e => e != null);
     
    309288      var execExpandExpressions = subContainer as IList<PushProgram> ?? subContainer.ToList();
    310289      return execExpandExpressions.Any()
    311           ? execExpandExpressions.OrderBy(c => c.State.Length).LastOrDefault()
    312           : current.State.Contains(target)
     290          ? execExpandExpressions.OrderBy(c => c.Expressions.Count).LastOrDefault()
     291          : current.Expressions.Contains(target)
    313292              ? current
    314293              : null;
     
    324303    public override bool Eval(IPushInterpreter interpreter) {
    325304      if (interpreter.CodeStack.Count < 2 ||
    326          !interpreter.CodeStack[interpreter.CodeStack.Count - 2].CanExpand)
     305         !interpreter.CodeStack[interpreter.CodeStack.Count - 2].IsProgram)
    327306        return false;
    328307
    329308      var values = interpreter.CodeStack.Pop(2);
    330309      var second = (PushProgram)values[0];
    331       var contains = second.State.Contains(values[1]);
     310      var contains = second.Expressions.Contains(values[1]);
    332311
    333312      interpreter.BooleanStack.Push(contains);
     
    413392
    414393    private void DetermineUniqueItems(Expression source, IDictionary<int, int> items) {
    415       if (source.CanExpand) {
    416         var expand = source as PushProgram;
    417 
    418         foreach (var e in expand.State) {
    419           var id = e.GetHashCode();
     394      if (source.IsProgram) {
     395        var program = source as PushProgram;
     396        var expressions = program.Expressions;
     397
     398        for (var i = 0; i < expressions.Count; i++) {
     399          var id = expressions[i].GetHashCode();
    420400          if (!items.ContainsKey(id)) items.Add(id, 1);
    421401          else items[id]++;
     
    442422      if (interpreter.IntegerStack.Count == 0 ||
    443423          interpreter.CodeStack.Count == 0 ||
    444           !interpreter.CodeStack.Top.CanExpand)
     424          !interpreter.CodeStack.Top.IsProgram)
    445425        return false;
    446426
     
    532512      if (interpreter.IntegerStack.Count == 0 ||
    533513          interpreter.CodeStack.Count < 2 ||
    534           !interpreter.CodeStack.Top.CanExpand)
     514          !interpreter.CodeStack.Top.IsProgram)
    535515        return false;
    536516
     
    540520
    541521      Expression[] newExpressions;
    542       if (target.State.Length > 0) {
    543         index = target.State.Length - 1 - Math.Abs(index % target.State.Length);
     522      if (!target.IsEmpty) {
     523        index = target.Expressions.Count - 1 - Math.Abs(index % target.Expressions.Count);
    544524
    545525        newExpressions = target.CopyExpressions();
    546         newExpressions[index] = source.CanExpand
    547             ? ((PushProgram)source).Copy()
     526        newExpressions[index] = source.IsProgram
     527            ? ((PushProgram)source).Copy(interpreter.PushProgramPool)
    548528            : source;
    549529      } else {
     
    551531      }
    552532
    553       var result = new PushProgram(newExpressions);
     533      var result = PushProgram.Create(interpreter.PushProgramPool, newExpressions);
    554534      interpreter.CodeStack.SetTop(result);
    555535
     
    572552      var count = 1;
    573553
    574       if (expression.CanExpand)
    575         count = ((PushProgram)expression).State.Length;
     554      if (expression.IsProgram)
     555        count = ((PushProgram)expression).Expressions.Count;
    576556
    577557      interpreter.IntegerStack.Push(count);
     
    591571      var first = interpreter.CodeStack.Pop();
    592572      var second = interpreter.CodeStack.Top;
    593       var expandExpression = new PushProgram(second, first);
     573      var expandExpression = PushProgram.Create(interpreter.PushProgramPool, second, first);
    594574
    595575      interpreter.CodeStack.SetTop(expandExpression);
     
    610590      var expressions = interpreter.CodeStack.Pop(2);
    611591
    612       var contains = expressions[1].CanExpand
    613           ? ((PushProgram)expressions[1]).State.Contains(expressions[0])
     592      var contains = expressions[1].IsProgram
     593          ? ((PushProgram)expressions[1]).Expressions.Contains(expressions[0])
    614594          : expressions[1].Equals(expressions[0]);
    615595
     
    635615      Expression nthExpression;
    636616
    637       if (expression.CanExpand) {
     617      if (expression.IsProgram) {
    638618        var subExpression = (PushProgram)expression;
    639619
     
    641621          nthExpression = PushProgram.Empty;
    642622        } else {
    643           var index = (int)(subExpression.State.Length - 1 -
    644                              Math.Abs(n % subExpression.State.Length));
    645 
    646           nthExpression = subExpression.State[index];
     623          var index = (int)(subExpression.Expressions.Count - 1 - Math.Abs(n % subExpression.Expressions.Count));
     624
     625          nthExpression = subExpression.Expressions[index];
    647626        }
    648627      } else {
     
    674653      Expression nthExpression;
    675654
    676       if (expression.CanExpand) {
    677         var subExpressions = ((PushProgram)expression).State;
    678 
    679         if (subExpressions.Length < 2) {
     655      if (expression.IsProgram) {
     656        var subExpressions = ((PushProgram)expression).Expressions;
     657
     658        if (subExpressions.Count < 2) {
    680659          nthExpression = PushProgram.Empty;
    681660        } else {
    682           var index = (int)(subExpressions.Length - 2 - Math.Abs(n % (subExpressions.Length - 1)));
     661          var index = (int)(subExpressions.Count - 2 - Math.Abs(n % (subExpressions.Count - 1)));
    683662
    684663          nthExpression = subExpressions[index];
     
    723702
    724703      var position = -1;
    725       if (first.CanExpand) {
    726         var expand = (PushProgram)first;
    727         position = expand.State.Length - 1
    728                    - Array.FindIndex((Expression[])expand.State, e => e.Equals(second));
     704      if (first.IsProgram) {
     705        var program = (PushProgram)first;
     706        position = program.Expressions.Count - 1 - program.IndexOf(second);
    729707      } else if (first.Equals(second)) {
    730708        position = 0;
     
    747725
    748726      var expression = interpreter.CodeStack.Pop();
    749       var points = expression.CanExpand
    750           ? ((PushProgram)expression).State.Length
     727      var points = expression.IsProgram
     728          ? ((PushProgram)expression).Expressions.Count
    751729          : 1;
    752730
     
    773751      var second = expressions[0];
    774752      var first = expressions[1] as PushProgram;
    775       var newExpressions = new Expression[first.State.Length];
    776 
    777       for (var i = 0; i < first.State.Length; i++)
    778         newExpressions[i] = first.State[i].Equals(third)
     753      var firstExpressions = first.Expressions;
     754      var newExpressions = new Expression[firstExpressions.Count];
     755
     756      for (var i = 0; i < firstExpressions.Count; i++)
     757        newExpressions[i] = firstExpressions[i].Equals(third)
    779758            ? second
    780759            /* no cloning needed here because first is removed and therefore newExpression is the only container of sub expressions */
    781             : first.State[i];
    782 
    783       var result = new PushProgram(newExpressions);
     760            : firstExpressions[i];
     761
     762      var result = PushProgram.Create(interpreter.PushProgramPool, newExpressions);
    784763
    785764      interpreter.CodeStack.SetTop(result);
Note: See TracChangeset for help on using the changeset viewer.