I have a tree of data representing a mathematical function, like this:

It is stored in arrays, so 2+3^2 would be represented as:
["+", 2, ["^2", 3] ]
To actually evaluate the tree, I have a recursive function
function evaluate(mathstructure::Array)
if mathstructure[1] == "+"
# do the operation
evaluate(mathstructure[2]) + evaluate(mathstructure[3])
elseif mathstructure[1] == "*"
# do the operation
evaluate(mathstructure[2]) * evaluate(mathstructure[3])
elseif mathstructure[1] == "σ"
# do the operation
x = evaluate(mathstructure[2])
1 / (1 + exp(-x))
elseif mathstructure[1] == "^2"
# do the operation
x = evaluate(mathstructure[2])
x^2
end
end
function evaluate(mathstructure::Variable)
mathstructure.value
end
(I actually have a Variable structure which has a value and an identifier to represent numbers, so I can change constants later)
This code works, but it is extremely slow. What steps should I take to optimize its performance? I can't use tail recursion because oftentimes the function calls its self twice.
Thank you!
-Diego