You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello guys,
I use math.js in my dashboard-application to give users the ability to customize the calculation of some diagrams.
So I'm more focused on the basics of the expression-parser than mathematical funcionality.
Now I try to make the evaluation faster, as sometimes many rows needs to be processed (via scope). Of course math.js can't be as fast as native JavaScript-code, but it would be nice to get a bit of speed-up. As I already compile the expression only once and then evaluate it thousands of times, I was looking for other ways to make the execution faster.
One approach is to use "simplify()" on my expression-string before compile it.
My other question is why "simpify()" not works for some types of nodes (see "simplifyConstant.js"):
// destroys the original node and returns a folded one
function foldFraction (node, options) {
switch (node.type) {
...
case 'BlockNode':
/* falls through */
case 'FunctionAssignmentNode':
/* falls through */
case 'RangeNode':
/* falls through */
case 'ConditionalNode':
/* falls through */
default:
throw new Error(`Unimplemented node type in simplifyConstant: ${node.type}`)
}
}
So it can't be used if any BlockNode, ConditionalNode, etc. is present.
Why dont implement it sth. like this?:
// destroys the original node and returns a folded one
function foldFraction (node, options) {
switch (node.type) {
...
case 'AssignmentNode':
return new AssignmentNode(node.object, node.index, simplifyConstant(node.value))
case 'BlockNode':
return new BlockNode(node.blocks.map(block => ({ node: simplifyConstant(block.node), visible: block.visible })))
// TODO: move not visible assignment-nodes
case 'FunctionAssignmentNode':
return new AssignmentNode(node.name, node.params, simplifyConstant(node.expression))
case 'RangeNode':
return node
case 'ConditionalNode':
return new ConditionalNode(simplifyConstant(node.condition),
simplifyConstant(node.trueExpr), simplifyConstant(node.falseExpr))
// TODO: replace node if condition is constant
default:
throw new Error(`Unimplemented node type in simplifyConstant: ${node.type}`)
}
}
This would simplify constant conditions like "( 5 > 2 + 2 ) ? 1 : 2 + 4" to "1 ? 1 : 6"
or assignments like "b = 2 + 3" to "b = 5"
And my last question: If not available on "simplify()", are such control-flow optimations done on compile step?
If the resulting expression from simplify is really simpler than the original, it can be faster to execute indeed. If that helps depends on what your bottleneck currently is, to figure that out requires some benchmarking I guess.
There are still ways to improve simplify, and you just found a piece that is still missing. Your approach to implement it is right. A PR improving this would be welcome :)
There is a bit of optimization done based on the current configuration for example, but nothing like simplify. It is a 1-to-1 compilation of your expression tree. You can check out the _compile() methods of all Node classes to see what's going on.
It will probably also help to evaluate the function getEarning only once instead of defining it repeatedly. Your example "Code 1" simply does do a bit more than "Code 2": it defines a function getEarning and a variable earnings. That could also be the reason that it executes slower.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hello guys,
I use math.js in my dashboard-application to give users the ability to customize the calculation of some diagrams.
So I'm more focused on the basics of the expression-parser than mathematical funcionality.
Now I try to make the evaluation faster, as sometimes many rows needs to be processed (via scope). Of course math.js can't be as fast as native JavaScript-code, but it would be nice to get a bit of speed-up. As I already compile the expression only once and then evaluate it thousands of times, I was looking for other ways to make the execution faster.
One approach is to use "simplify()" on my expression-string before compile it.
So my first question: Does this help to get faster expressions? As mentioned here (https://mathjs.org/docs/expressions/security.html) the compile-step "does as much as possible preprocessing"
My other question is why "simpify()" not works for some types of nodes (see "simplifyConstant.js"):
So it can't be used if any BlockNode, ConditionalNode, etc. is present.
Why dont implement it sth. like this?:
This would simplify constant conditions like "( 5 > 2 + 2 ) ? 1 : 2 + 4" to "1 ? 1 : 6"
or assignments like "b = 2 + 3" to "b = 5"
Thanks for answer my questions!
Beta Was this translation helpful? Give feedback.
All reactions