uCalc API Version: 5.7.0-preview.1 Released: 7/30/2026
Warning
uCalc API Preview Release Notice:This preview documentation describes the intended behavior of the API. It is not fully accurate or complete.The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.Use of the preview version in your production code is not recommended.
Explains the 'Parse-Once, Evaluate-Many' pattern for writing high-performance expressions in loops.
While uCalc's expression parser is highly optimized, the single most important factor for achieving maximum performance is understanding the difference between parsing and evaluation. For expressions that are executed repeatedly, such as inside a loop, using the "Parse-Once, Evaluate-Many" pattern is critical.
This guide explains why this pattern is so effective and how to implement it.
When you call a convenience method like Eval() or EvalStr(), the uCalc engine performs two major steps:
Calling these methods inside a loop forces the engine to re-parse the same expression string over and over again, which is highly inefficient.
The following code is simple but will perform poorly if the loop runs many times, as "x * x + 2" is parsed on every single iteration.csharp
// Inefficient: The expression string is parsed on every iteration.
for ( i = 1; i <= 1000; i++) {
uc.DefineVariable("x = " + i);
Console.WriteLine(uc.Eval("x * x + 2"));
}
The correct approach is to separate the expensive parsing step from the fast evaluation step.
.Evaluate() or .EvaluateStr() method on the pre-parsed object.This code is significantly faster because the parsing work is done only once.csharp
// Efficient: The expression is parsed once, before the loop begins.
var x_var = uc.DefineVariable("x");
var expr = uc.Parse("x * x + 2");
for ( i = 1; i <= 1000; i++) {
x_var.Value(i);
// The Evaluate() step is extremely fast.
Console.WriteLine(expr.Evaluate());
}
}
Eval() Okay?Convenience methods like Eval() and EvalStr() are perfectly acceptable for one-off calculations or in non-performance-critical parts of your application. The "Parse-Once" pattern is specifically designed for scenarios involving repeated evaluation of the same expression structure.
uCalc's two-step evaluation model provides a significant advantage over other common methods for evaluating strings at runtime.
vs. C# DataTable.Compute: The common .NET workaround for evaluating strings is slow and lacks features. It must re-parse the expression on every call, making it unsuitable for performance-critical loops.
vs. eval() in Scripting Languages: Functions like eval() in Python or JavaScript are also convenient but typically re-parse on every call. They also carry the overhead of a full scripting engine.
vs. C# Expression Trees: Building a compiled delegate from a C# Expression Tree provides similar performance benefits, but constructing that tree from a raw string at runtime is a complex, multi-step process. uCalc's Parse() method provides a simple, direct way to get a high-performance, pre-compiled object from a string, offering the best of both worlds: runtime flexibility and near-native execution speed.
ID: 1192
using uCalcSoftware;
var uc = new uCalc();
// 1. Parse the expression string once to create a reusable object.
//var expr = uc.Parse("5 * 10");
using (var expr = new uCalc.Expression("5 * 10")) {
// 2. Evaluate the pre-parsed object as many times as needed.
Console.WriteLine(expr.Evaluate());
Console.WriteLine(expr.Evaluate());
} // The expression object is automatically released here.
50
50 using uCalcSoftware; var uc = new uCalc(); // 1. Parse the expression string once to create a reusable object. //var expr = uc.Parse("5 * 10"); using (var expr = new uCalc.Expression("5 * 10")) { // 2. Evaluate the pre-parsed object as many times as needed. Console.WriteLine(expr.Evaluate()); Console.WriteLine(expr.Evaluate()); } // The expression object is automatically released here.
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
// 1. Parse the expression string once to create a reusable object.
//var expr = uc.Parse("5 * 10");
{
uCalc::Expression expr("5 * 10");
expr.Owned(); // Causes expr to be released when it goes out of scope
// 2. Evaluate the pre-parsed object as many times as needed.
cout << expr.Evaluate() << endl;
cout << expr.Evaluate() << endl;
} // The expression object is automatically released here.
}
50
50 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; // 1. Parse the expression string once to create a reusable object. //var expr = uc.Parse("5 * 10"); { uCalc::Expression expr("5 * 10"); expr.Owned(); // Causes expr to be released when it goes out of scope // 2. Evaluate the pre-parsed object as many times as needed. cout << expr.Evaluate() << endl; cout << expr.Evaluate() << endl; } // The expression object is automatically released here. }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
'// 1. Parse the expression string once to create a reusable object.
'//var expr = uc.Parse("5 * 10");
Using expr As New uCalc.Expression("5 * 10")
'// 2. Evaluate the pre-parsed object as many times as needed.
Console.WriteLine(expr.Evaluate())
Console.WriteLine(expr.Evaluate())
End Using '// The expression object is automatically released here.
End Sub
End Module
50
50 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() '// 1. Parse the expression string once to create a reusable object. '//var expr = uc.Parse("5 * 10"); Using expr As New uCalc.Expression("5 * 10") '// 2. Evaluate the pre-parsed object as many times as needed. Console.WriteLine(expr.Evaluate()) Console.WriteLine(expr.Evaluate()) End Using '// The expression object is automatically released here. End Sub End Module
ID: 1460
using uCalcSoftware;
var uc = new uCalc();
var variableX = uc.DefineVariable("x");
var userExpression = "x * 2 + 5";
var Total = 0.0;
var UpperBound = 1000000; // One million
// Parse the expression just once before the loop begins.
var parsedExpr = uc.Parse(userExpression);
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
for (double x = 1; x <= UpperBound; x++) {
variableX.Value(x);
Total = Total + parsedExpr.Evaluate();
}
stopwatch.Stop();
//Uncomment the following line to reveal the actual speed:
//Console.WriteLine($"Elapsed Milliseconds: {stopwatch.ElapsedMilliseconds} ms");
Console.Write("Sum(1, "); Console.Write(UpperBound); Console.Write(", "); Console.Write(userExpression); Console.Write(") = "); Console.Write(Total);
Sum(1, 1000000, x * 2 + 5) = 1000006000000 using uCalcSoftware; var uc = new uCalc(); var variableX = uc.DefineVariable("x"); var userExpression = "x * 2 + 5"; var Total = 0.0; var UpperBound = 1000000; // One million // Parse the expression just once before the loop begins. var parsedExpr = uc.Parse(userExpression); var stopwatch = System.Diagnostics.Stopwatch.StartNew(); for (double x = 1; x <= UpperBound; x++) { variableX.Value(x); Total = Total + parsedExpr.Evaluate(); } stopwatch.Stop(); //Uncomment the following line to reveal the actual speed: //Console.WriteLine($"Elapsed Milliseconds: {stopwatch.ElapsedMilliseconds} ms"); Console.Write("Sum(1, "); Console.Write(UpperBound); Console.Write(", "); Console.Write(userExpression); Console.Write(") = "); Console.Write(Total);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto variableX = uc.DefineVariable("x");
auto userExpression = "x * 2 + 5";
auto Total = 0.0;
auto UpperBound = 1000000; // One million
// Parse the expression just once before the loop begins.
auto parsedExpr = uc.Parse(userExpression);
for (double x = 1; x <= UpperBound; x++) {
variableX.Value(x);
Total = Total + parsedExpr.Evaluate();
}
cout << "Sum(1, " << UpperBound << ", " << userExpression << ") = " << (long long)Total;
}
Sum(1, 1000000, x * 2 + 5) = 1000006000000 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto variableX = uc.DefineVariable("x"); auto userExpression = "x * 2 + 5"; auto Total = 0.0; auto UpperBound = 1000000; // One million // Parse the expression just once before the loop begins. auto parsedExpr = uc.Parse(userExpression); for (double x = 1; x <= UpperBound; x++) { variableX.Value(x); Total = Total + parsedExpr.Evaluate(); } cout << "Sum(1, " << UpperBound << ", " << userExpression << ") = " << (long long)Total; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim variableX = uc.DefineVariable("x")
Dim userExpression = "x * 2 + 5"
Dim Total = 0.0
Dim UpperBound = 1000000 '// One million
'// Parse the expression just once before the loop begins.
Dim parsedExpr = uc.Parse(userExpression)
Dim stopwatch = System.Diagnostics.Stopwatch.StartNew()
For x As Double = 1 To UpperBound
variableX.Value(x)
Total = Total + parsedExpr.Evaluate()
Next
stopwatch.Stop()
'//Uncomment the following line to reveal the actual speed:
'//Console.WriteLine($"Elapsed Milliseconds: {stopwatch.ElapsedMilliseconds} ms");
Console.Write("Sum(1, ")
Console.Write(UpperBound)
Console.Write(", ")
Console.Write(userExpression)
Console.Write(") = ")
Console.Write(Total)
End Sub
End Module
Sum(1, 1000000, x * 2 + 5) = 1000006000000 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim variableX = uc.DefineVariable("x") Dim userExpression = "x * 2 + 5" Dim Total = 0.0 Dim UpperBound = 1000000 '// One million '// Parse the expression just once before the loop begins. Dim parsedExpr = uc.Parse(userExpression) Dim stopwatch = System.Diagnostics.Stopwatch.StartNew() For x As Double = 1 To UpperBound variableX.Value(x) Total = Total + parsedExpr.Evaluate() Next stopwatch.Stop() '//Uncomment the following line to reveal the actual speed: '//Console.WriteLine($"Elapsed Milliseconds: {stopwatch.ElapsedMilliseconds} ms"); Console.Write("Sum(1, ") Console.Write(UpperBound) Console.Write(", ") Console.Write(userExpression) Console.Write(") = ") Console.Write(Total) End Sub End Module
ID: 1193
using uCalcSoftware;
var uc = new uCalc();
var x_var = uc.DefineVariable("x");
var i = 0;
// --- Inefficient Way ---
Console.WriteLine("--- Inefficient: Eval() in a loop ---");
for ( i = 1; i <= 3; i++) {
x_var.Value(i);
Console.WriteLine(uc.Eval("x * x + 2"));
}
Console.WriteLine("");
// --- High-Performance Way ---
Console.WriteLine("--- Efficient: Parse() once, Evaluate() in a loop ---");
// Parse outside the loop
var expr = uc.Parse("x * x + 2");
for ( i = 1; i <= 3; i++) {
x_var.Value(i);
// Evaluate the pre-parsed object
Console.WriteLine(expr.Evaluate());
}
--- Inefficient: Eval() in a loop ---
3
6
11
--- Efficient: Parse() once, Evaluate() in a loop ---
3
6
11 using uCalcSoftware; var uc = new uCalc(); var x_var = uc.DefineVariable("x"); var i = 0; // --- Inefficient Way --- Console.WriteLine("--- Inefficient: Eval() in a loop ---"); for ( i = 1; i <= 3; i++) { x_var.Value(i); Console.WriteLine(uc.Eval("x * x + 2")); } Console.WriteLine(""); // --- High-Performance Way --- Console.WriteLine("--- Efficient: Parse() once, Evaluate() in a loop ---"); // Parse outside the loop var expr = uc.Parse("x * x + 2"); for ( i = 1; i <= 3; i++) { x_var.Value(i); // Evaluate the pre-parsed object Console.WriteLine(expr.Evaluate()); }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto x_var = uc.DefineVariable("x");
auto i = 0;
// --- Inefficient Way ---
cout << "--- Inefficient: Eval() in a loop ---" << endl;
for ( i = 1; i <= 3; i++) {
x_var.Value(i);
cout << uc.Eval("x * x + 2") << endl;
}
cout << "" << endl;
// --- High-Performance Way ---
cout << "--- Efficient: Parse() once, Evaluate() in a loop ---" << endl;
// Parse outside the loop
auto expr = uc.Parse("x * x + 2");
for ( i = 1; i <= 3; i++) {
x_var.Value(i);
// Evaluate the pre-parsed object
cout << expr.Evaluate() << endl;
}
}
--- Inefficient: Eval() in a loop ---
3
6
11
--- Efficient: Parse() once, Evaluate() in a loop ---
3
6
11 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto x_var = uc.DefineVariable("x"); auto i = 0; // --- Inefficient Way --- cout << "--- Inefficient: Eval() in a loop ---" << endl; for ( i = 1; i <= 3; i++) { x_var.Value(i); cout << uc.Eval("x * x + 2") << endl; } cout << "" << endl; // --- High-Performance Way --- cout << "--- Efficient: Parse() once, Evaluate() in a loop ---" << endl; // Parse outside the loop auto expr = uc.Parse("x * x + 2"); for ( i = 1; i <= 3; i++) { x_var.Value(i); // Evaluate the pre-parsed object cout << expr.Evaluate() << endl; } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim x_var = uc.DefineVariable("x")
Dim i = 0
'// --- Inefficient Way ---
Console.WriteLine("--- Inefficient: Eval() in a loop ---")
For i = 1 To 3
x_var.Value(i)
Console.WriteLine(uc.Eval("x * x + 2"))
Next
Console.WriteLine("")
'// --- High-Performance Way ---
Console.WriteLine("--- Efficient: Parse() once, Evaluate() in a loop ---")
'// Parse outside the loop
Dim expr = uc.Parse("x * x + 2")
For i = 1 To 3
x_var.Value(i)
'// Evaluate the pre-parsed object
Console.WriteLine(expr.Evaluate())
Next
End Sub
End Module
--- Inefficient: Eval() in a loop ---
3
6
11
--- Efficient: Parse() once, Evaluate() in a loop ---
3
6
11 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim x_var = uc.DefineVariable("x") Dim i = 0 '// --- Inefficient Way --- Console.WriteLine("--- Inefficient: Eval() in a loop ---") For i = 1 To 3 x_var.Value(i) Console.WriteLine(uc.Eval("x * x + 2")) Next Console.WriteLine("") '// --- High-Performance Way --- Console.WriteLine("--- Efficient: Parse() once, Evaluate() in a loop ---") '// Parse outside the loop Dim expr = uc.Parse("x * x + 2") For i = 1 To 3 x_var.Value(i) '// Evaluate the pre-parsed object Console.WriteLine(expr.Evaluate()) Next End Sub End Module
ID: 1194
using uCalcSoftware;
var uc = new uCalc();
uc.DefineFunction("Calc(a, b) = a * 2 - b");
var x_var = uc.DefineVariable("x");
var y_var = uc.DefineVariable("y");
var i = 0;
var expr = uc.Parse("Calc(x, y) + Sqrt(x)");
for ( i = 1; i <= 4; i++) {
x_var.Value(i * i); // Use squared values for x
y_var.Value(i); // Use linear values for y
Console.WriteLine(expr.Evaluate());
}
2
8
18
32 using uCalcSoftware; var uc = new uCalc(); uc.DefineFunction("Calc(a, b) = a * 2 - b"); var x_var = uc.DefineVariable("x"); var y_var = uc.DefineVariable("y"); var i = 0; var expr = uc.Parse("Calc(x, y) + Sqrt(x)"); for ( i = 1; i <= 4; i++) { x_var.Value(i * i); // Use squared values for x y_var.Value(i); // Use linear values for y Console.WriteLine(expr.Evaluate()); }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uc.DefineFunction("Calc(a, b) = a * 2 - b");
auto x_var = uc.DefineVariable("x");
auto y_var = uc.DefineVariable("y");
auto i = 0;
auto expr = uc.Parse("Calc(x, y) + Sqrt(x)");
for ( i = 1; i <= 4; i++) {
x_var.Value(i * i); // Use squared values for x
y_var.Value(i); // Use linear values for y
cout << expr.Evaluate() << endl;
}
}
2
8
18
32 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uc.DefineFunction("Calc(a, b) = a * 2 - b"); auto x_var = uc.DefineVariable("x"); auto y_var = uc.DefineVariable("y"); auto i = 0; auto expr = uc.Parse("Calc(x, y) + Sqrt(x)"); for ( i = 1; i <= 4; i++) { x_var.Value(i * i); // Use squared values for x y_var.Value(i); // Use linear values for y cout << expr.Evaluate() << endl; } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
uc.DefineFunction("Calc(a, b) = a * 2 - b")
Dim x_var = uc.DefineVariable("x")
Dim y_var = uc.DefineVariable("y")
Dim i = 0
Dim expr = uc.Parse("Calc(x, y) + Sqrt(x)")
For i = 1 To 4
x_var.Value(i * i) '// Use squared values for x
y_var.Value(i) '// Use linear values for y
Console.WriteLine(expr.Evaluate())
Next
End Sub
End Module
2
8
18
32 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() uc.DefineFunction("Calc(a, b) = a * 2 - b") Dim x_var = uc.DefineVariable("x") Dim y_var = uc.DefineVariable("y") Dim i = 0 Dim expr = uc.Parse("Calc(x, y) + Sqrt(x)") For i = 1 To 4 x_var.Value(i * i) '// Use squared values for x y_var.Value(i) '// Use linear values for y Console.WriteLine(expr.Evaluate()) Next End Sub End Module