diff --git a/Expressions/FunctionCall.cs b/Expressions/FunctionCall.cs index 258cac17..3b960feb 100644 --- a/Expressions/FunctionCall.cs +++ b/Expressions/FunctionCall.cs @@ -107,11 +107,16 @@ public void GatherMatchingFunctionCalls(ICollection matchingFuncti } } + private IMathObject[] _evaledArgsCache = new IMathObject[0]; + // Warning: Not thread-safe public virtual IMathObject Call(SolusEnvironment env) { - var evaledArgs = - Arguments.Select(a => a.Eval(env)).ToArray(); - return Function.Call(env, evaledArgs); + if (_evaledArgsCache.Length < Arguments.Count) + _evaledArgsCache = new IMathObject[Arguments.Count]; + int i; + for (i = 0; i < Arguments.Count; i++) + _evaledArgsCache[i] = Arguments[i].Eval(env); + return Function.Call(env, _evaledArgsCache); } public virtual List Arguments diff --git a/Expressions/Literal.cs b/Expressions/Literal.cs index 53f0619a..471b58f5 100644 --- a/Expressions/Literal.cs +++ b/Expressions/Literal.cs @@ -76,7 +76,7 @@ public virtual IMathObject Value if (_value != value) { _value = value; - this.OnValueChanged(new EventArgs()); + this.OnValueChanged(EventArgs.Empty); } } } diff --git a/Expressions/VariableAccess.cs b/Expressions/VariableAccess.cs index d4435ecb..63cbec31 100644 --- a/Expressions/VariableAccess.cs +++ b/Expressions/VariableAccess.cs @@ -55,7 +55,7 @@ public override IMathObject Eval(SolusEnvironment env) if (env.ContainsVariable(var)) { if (env.GetVariable(var) is Literal literal) - return literal.Value.ToNumber(); + return literal.Value; return env.GetVariable(var).Eval(env); } diff --git a/Expressions/VectorExpression.cs b/Expressions/VectorExpression.cs index 40519fa9..fbd043e2 100644 --- a/Expressions/VectorExpression.cs +++ b/Expressions/VectorExpression.cs @@ -101,7 +101,8 @@ public override IMathObject Eval(SolusEnvironment env) var values = new IMathObject[Length]; for (int i = 0; i < Length; i++) values[i] = this[i].Eval(env); - return new Vector(values); + // Vector will take ownership of array + return new Vector(values); // TODO: don't box here } public override Expression Clone() @@ -214,19 +215,30 @@ public override void AcceptVisitor(IExpressionVisitor visitor) } } + private Expression[] _valuesCache = null; public override Expression PreliminaryEval(SolusEnvironment env) { - var values = _array.Select( - e => e.PreliminaryEval(env)).ToArray(); - if (values.All(e => e is Literal)) + if (_valuesCache == null || + _valuesCache.Length < _array.Length) + _valuesCache = new Expression[_array.Length]; + + bool allLiterals = true; + int i; + for (i = 0; i < _array.Length; i++) + { + var e = _valuesCache[i] = _array[i].PreliminaryEval(env); + allLiterals &= e is Literal; + } + if (allLiterals) { - return new Literal( - new Vector( - values.Select( - e => ((Literal) e).Value).ToArray())); + var values = new IMathObject[_valuesCache.Length]; + for (i = 0; i < _array.Length; i++) + values[i] = ((Literal)_valuesCache[i]).Value; + // Vector will take ownership of array + return new Literal(new Vector(values)); } - return new VectorExpression(values.Length, values); + return new VectorExpression(_valuesCache.Length, _valuesCache); } public override void ApplyToAll(Modulator mod) diff --git a/Values/Vector.cs b/Values/Vector.cs index 60956fe4..c7535a05 100644 --- a/Values/Vector.cs +++ b/Values/Vector.cs @@ -29,6 +29,7 @@ namespace MetaphysicsIndustries.Solus.Values { public Vector(IMathObject[] components) { + // TODO: don't clone here _components = (IMathObject[]) components.Clone(); var componentType = _components[0].GetMathType();