Index: branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeLinearCompiler.cs
===================================================================
--- branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeLinearCompiler.cs	(revision 9793)
+++ branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeLinearCompiler.cs	(revision 9815)
@@ -21,6 +21,4 @@
 
 using System;
-using System.Collections.Generic;
-using System.Linq;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
@@ -28,15 +26,17 @@
     public static LinearInstruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper) {
       var root = tree.Root.GetSubtree(0).GetSubtree(0);
-      var code = new List<LinearInstruction> {
-          new LinearInstruction { dynamicNode = root, nArguments = (byte)root.SubtreeCount, opCode = opCodeMapper(root) }
-        };
-      // iterate breadth-wise over tree nodes and produce an array of instructions
-      var nodes = root.IterateNodesBreadth().ToArray();
-      for (int i = 0; i != nodes.Length; ++i) {
-        code[i].childIndex = (byte)code.Count;
-        code.AddRange(nodes[i].Subtrees.Select(s => new LinearInstruction { dynamicNode = s, nArguments = (byte)s.SubtreeCount, opCode = opCodeMapper(s) }));
+      var code = new LinearInstruction[root.GetLength()];
+      code[0] = new LinearInstruction { dynamicNode = root, nArguments = (byte)root.SubtreeCount, opCode = opCodeMapper(root) };
+      int c = 1, i = 0;
+      foreach (var node in root.IterateNodesBreadth()) {
+        for (int j = 0; j != node.SubtreeCount; ++j) {
+          var s = node.GetSubtree(j);
+          code[c + j] = new LinearInstruction { dynamicNode = s, nArguments = (byte)s.SubtreeCount, opCode = opCodeMapper(s) };
+        }
+        code[i].childIndex = (byte)c;
+        c += node.SubtreeCount;
+        ++i;
       }
-
-      return code.ToArray();
+      return code;
     }
   }
Index: branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
===================================================================
--- branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 9793)
+++ branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 9815)
@@ -32,5 +32,5 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   [StorableClass]
-  [Item("SymbolicDataAnalysisExpressionTreeLinearInterpreter", "Linear (non-recursive) interpreter for symbolic expression trees. This interpreter is faster but does not support Integral, Derivative, TimeLag or ADF function nodes.")]
+  [Item("SymbolicDataAnalysisExpressionTreeLinearInterpreter", "Fast linear (non-recursive) interpreter for symbolic expression trees. Does not support ADFs.")]
   public sealed class SymbolicDataAnalysisExpressionTreeLinearInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
     private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
@@ -126,68 +126,4 @@
       PrepareInstructions(code, dataset);
       return rows.Select(row => Evaluate(dataset, ref row, code));
-    }
-
-    private static LinearInstruction[] GetPrefixSequence(LinearInstruction[] code, int startIndex) {
-      Action<LinearInstruction, List<LinearInstruction>> getPrefix = null;
-      getPrefix = (instr, list) => {
-        list.Add(instr);
-        for (int i = 0; i != instr.nArguments; ++i) {
-          getPrefix(code[instr.childIndex + i], list);
-        }
-      };
-      var l = new List<LinearInstruction>();
-      getPrefix(code[startIndex], l);
-      return l.ToArray();
-    }
-
-    private static void PrepareInstructions(LinearInstruction[] code, Dataset dataset) {
-      Action<LinearInstruction> setSkip = null;
-      setSkip = instruction => {
-        instruction.skip = true;
-        for (int j = 0; j != instruction.nArguments; ++j) {
-          setSkip(code[instruction.childIndex + j]);
-        }
-      };
-
-      for (int i = 0; i != code.Length; ++i) {
-        var instr = code[i];
-        #region opcode switch
-        switch (instr.opCode) {
-          case OpCodes.Constant: {
-              var constTreeNode = (ConstantTreeNode)instr.dynamicNode;
-              instr.value = constTreeNode.Value;
-              instr.skip = true; // the value is already set so this instruction should be skipped in the evaluation phase
-            }
-            break;
-          case OpCodes.Variable: {
-              var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
-              instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
-            }
-            break;
-          case OpCodes.LagVariable: {
-              var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
-              instr.iArg0 = dataset.GetReadOnlyDoubleValues(laggedVariableTreeNode.VariableName);
-            }
-            break;
-          case OpCodes.VariableCondition: {
-              var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
-              instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableConditionTreeNode.VariableName);
-            }
-            break;
-          case OpCodes.TimeLag:
-          case OpCodes.Integral:
-          case OpCodes.Derivative: {
-              Instruction[] seq = GetPrefixSequence(code, i);
-              var interpreterState = new InterpreterState(seq, 0);
-              instr.iArg0 = interpreterState;
-              for (int j = 0; j != instr.nArguments; ++j) {
-                // the linear evaluator will skip these instructions and they will be evaluated using the default (recursive) evaluator
-                setSkip(code[instr.childIndex + j]);
-              }
-            }
-            break;
-        }
-        #endregion
-      }
     }
 
@@ -489,4 +425,56 @@
       return code[0].value;
     }
+
+    private static LinearInstruction[] GetPrefixSequence(LinearInstruction[] code, int startIndex) {
+      var list = new List<LinearInstruction>();
+      int i = startIndex;
+      while (i != code.Length) {
+        var instr = code[i];
+        list.Add(instr);
+        i = instr.nArguments > 0 ? instr.childIndex : i + 1;
+      }
+      return list.ToArray();
+    }
+
+    private static void PrepareInstructions(LinearInstruction[] code, Dataset dataset) {
+      for (int i = 0; i != code.Length; ++i) {
+        var instr = code[i];
+        #region opcode switch
+        switch (instr.opCode) {
+          case OpCodes.Constant: {
+              var constTreeNode = (ConstantTreeNode)instr.dynamicNode;
+              instr.value = constTreeNode.Value;
+              instr.skip = true; // the value is already set so this instruction should be skipped in the evaluation phase
+            }
+            break;
+          case OpCodes.Variable: {
+              var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
+              instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
+            }
+            break;
+          case OpCodes.LagVariable: {
+              var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
+              instr.iArg0 = dataset.GetReadOnlyDoubleValues(laggedVariableTreeNode.VariableName);
+            }
+            break;
+          case OpCodes.VariableCondition: {
+              var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
+              instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableConditionTreeNode.VariableName);
+            }
+            break;
+          case OpCodes.TimeLag:
+          case OpCodes.Integral:
+          case OpCodes.Derivative: {
+              var seq = GetPrefixSequence(code, i);
+              var interpreterState = new InterpreterState(seq, 0);
+              instr.iArg0 = interpreterState;
+              for (int j = 1; j != seq.Length; ++j)
+                seq[j].skip = true;
+            }
+            break;
+        }
+        #endregion
+      }
+    }
   }
 }
