I have a scenario where I need to evaluate one expression 1 million times, but on each iteration the only things that do change are the argument values:
var x1 = new Argument("X1", double.NaN);
var x2 = new Argument("X2", double.NaN);
var x3 = new Argument("X3", double.NaN);
Expression expression = new Expression(
"coalesce(X1, 0) + coalesce(X2, 0) + coalesce(X3, 0)",
x1, x2, x3);
var calculateElapsed = new List<double>();
var getComputingTime = new List<double>();
var s1 = mXparser.currentTimeMillis();
foreach (var i in Enumerable.Range(1, 1000000))
{
x1.setArgumentValue(i % 5 == 0 ? double.NaN : i % 5);
x2.setArgumentValue(i % 7 == 0 ? double.NaN : i % 7);
x3.setArgumentValue(i % 3 == 0 ? double.NaN : i % 3);
var s2 = mXparser.currentTimeMillis();
expression.calculate();
var e2 = mXparser.currentTimeMillis();
calculateElapsed.Add(e2 - s2);
getComputingTime.Add(expression.getComputingTime());
}
var e1 = mXparser.currentTimeMillis();
Based on the run's benchmark statistics, getComputingTime() is measuring significantly smaller values than getCurrentMillis() indicating some sort of pre-evaluation overheads.
-----------------------------------------------------------------------------------
| | Avg(ms) | Median(ms) | Min(ms) | Max(ms) | Total(ms) |
-----------------------------------------------------------------------------------
| getComputingTime | 0.000004 | 0.000000 | 0.000000 | 0.121000 | 4.206000 |
-----------------------------------------------------------------------------------
| calculate() | 0.004300 | 0.000000 | 0.000000 | 131.000000 | 4,300.000000 |
-----------------------------------------------------------------------------------
I am not sure what overhead this should be, since I would assume the expression does not change so we only need to parse once.
Is there some sort of configuration or pattern that would allow me to reduce this overhead cost of calculate() when the expression is the same and only the arguments values are varying?