Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
eval vs new Function vs mathjs vs infix parse
(version: 0)
Comparing performance of:
eval vs new Function vs mathjs vs evaluateExpression
Created:
3 years ago
by:
Guest
Jump to the latest result
HTML Preparation code:
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/6.6.1/math.min.js"></script>
Script Preparation code:
const supportedOperators = { '-': { precedence: 1, operate: (lhs, rhs) => lhs - rhs, }, '+': { precedence: 1, operate: (lhs, rhs) => lhs + rhs, }, '/': { precedence: 3, operate: (lhs, rhs) => lhs / rhs, }, '*': { precedence: 4, operate: (lhs, rhs) => lhs * rhs, }, '^': { precedence: 5, operate: (lhs, rhs) => lhs ** rhs, }, }; function isOperator(value) { return !!supportedOperators[value]; } function isOperand(value) { return !Number.isNaN(+value); } function getPrecedence(operator) { const supportedOperator = supportedOperators[operator]; if (!supportedOperator) { return -1; } return supportedOperator.precedence; } function evaluateLastOperation(operators, operands) { const operator = supportedOperators[operators.pop()]; const rhs = operands.pop(); const lhs = operands.pop(); return operator.operate(+lhs, +rhs); } function tokenizeExpression(expr) { const currentTokens = []; let currentValue = ''; for (let i = 0; i < expr.length; i += 1) { if (expr[i] === ' ') { if (currentValue) { currentTokens.push(currentValue); currentValue = ''; } } else if (expr[i] === ')') { if (currentValue) { currentTokens.push(currentValue); currentValue = ''; } currentTokens.push(')'); } else if (isOperand(expr[i]) || (expr[i] === '.' && currentValue.indexOf('.') === -1 && expr[i + 1]) || (expr[i] === '-' && currentValue.indexOf('-') === -1 && isOperand(expr[i + 1]))) { currentValue += expr[i]; } else if (expr[i] === '(' || expr[i] === ')' || isOperator(expr[i])) { currentTokens.push(expr[i]); } } if (currentValue) { currentTokens.push(currentValue); } return currentTokens; } function evaluateExpression(expr) { const tokens = tokenizeExpression(expr); const operands = []; const operators = []; tokens.forEach((token) => { if (isOperand(token)) { operands.push(token); } else if (token === '(') { operators.push(token); } else if (token === ')') { let operatorTop = operators[operators.length - 1]; while (operators.length && operatorTop !== '(') { operands.push(evaluateLastOperation(operators, operands)); operatorTop = operators[operators.length - 1]; } operators.pop(); } else if (isOperator(token)) { let operatorTop = operators[operators.length - 1]; while (operators.length && operatorTop !== '(' && getPrecedence(token) <= getPrecedence(operatorTop)) { operands.push(evaluateLastOperation(operators, operands)); operatorTop = operators[operators.length - 1]; } operators.push(token); } }); while (operators.length) { operands.push(evaluateLastOperation(operators, operands)); } return operands[0]; } var testMathExpression = `142 * ( 2 / 0.9 ) ^ -1.2 * 0.9938 ^ 50`; var func = new Function(`return ${testMathExpression}`);
Tests:
eval
eval(testMathExpression);
new Function
func();
mathjs
math.evaluate(testMathExpression);
evaluateExpression
evaluateExpression(testMathExpression);
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (4)
Previous results
Fork
Test case name
Result
eval
new Function
mathjs
evaluateExpression
Fastest:
N/A
Slowest:
N/A
Latest run results:
Run details:
(Test run date:
2 years ago
)
User agent:
Mozilla/5.0 (iPhone; CPU iPhone OS 17_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1
Browser/OS:
Mobile Safari 17 on iOS 17.2.1
View result in a separate tab
Embed
Embed Benchmark Result
Test name
Executions per second
eval
7952271.0 Ops/sec
new Function
29537648.0 Ops/sec
mathjs
154031.1 Ops/sec
evaluateExpression
170868.0 Ops/sec
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
**Benchmark Overview** The provided benchmark measures the performance of different approaches to evaluate mathematical expressions in JavaScript: `eval`, `new Function`, `mathjs` (a library for symbolic computation), and `evaluateExpression` (a custom implementation). **Tested Options** 1. **`eval(testMathExpression)`**: This method uses the built-in `eval()` function to execute a string as JavaScript code. 2. **`func();`**: This method creates a new anonymous function using `Function` constructor and passes the mathematical expression as a string argument. 3. **`math.evaluate(testMathExpression);`**: This method uses the `evaluate()` function from the `mathjs` library to evaluate the mathematical expression. 4. **`evaluateExpression(testMathExpression);`**: This is a custom implementation that tokenizes the expression, then evaluates it using a stack-based algorithm. **Pros and Cons of Each Approach** 1. **`eval()`**: * Pros: Simple to implement, widely supported. * Cons: Vulnerable to code injection attacks, can be slow due to dynamic compilation. 2. **`new Function()`**: * Pros: More secure than `eval()`, allows for sandboxing the expression. * Cons: Can be slower than `eval()` due to function creation overhead. 3. **`mathjs`**: * Pros: Provides a safe and efficient way to evaluate mathematical expressions, supports various input formats. * Cons: Requires external library dependency, can be overkill for simple cases. 4. **`evaluateExpression()`**: * Pros: Custom implementation that may optimize performance for specific use cases. * Cons: Requires more development effort, potentially less readable and maintainable. **Benchmark Results** The provided benchmark results show the number of executions per second for each test case on a mobile Safari 17 browser: | Test Case | Executions Per Second | | --- | --- | | `new Function` | 29,537,648 | | `eval` | 7,952,271 | | `evaluateExpression` | 1,708,68 | | `mathjs` | 15,403,11 | The results suggest that the custom implementation (`evaluateExpression`) is significantly slower than the other approaches. However, it's essential to note that this benchmark may not be representative of all use cases or environments. **Conclusion** The choice of evaluation method depends on the specific requirements and constraints of your project. If you need a simple, widely supported solution, `eval()` might be sufficient. For more secure and efficient evaluations, consider using `new Function()` or `mathjs`. The custom implementation (`evaluateExpression`) may not be the best choice for most use cases, but it could provide optimization opportunities for specific scenarios.
Related benchmarks:
JS Operator vs Function
?. operator vs. getProperty
object property lookup: in operator vs undefined comparison
Object creation vs function definition vs arror function vs function expression vs named function expression
prop access vs in operator
Comments
Confirm delete:
Do you really want to delete benchmark?