uCalc API Version: 2.1.3-preview.2 Released: 6/17/2026
Warning
uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.
Performance considerations
Product:
Class:
A guide to the key architectural patterns and best practices for writing high-performance code with the uCalc engine.
Remarks
⚡ Writing High-Performance uCalc Code
While the uCalc engine is highly optimized out of the box, understanding its core architecture is essential for achieving maximum performance in demanding applications. This guide summarizes the most important patterns and best practices for writing efficient code.
For a step-by-step guide on the most critical optimization, see the Optimizing Performance tutorial.
The Core Principle: Parse vs. Evaluate
The single most important concept for performance is the separation of parsing from evaluation.
- Parsing: The computationally expensive step of analyzing a string, tokenizing it, and building an executable plan (an abstract syntax tree). This is done by methods like Parse.
- Evaluation: The extremely fast step of executing that pre-compiled plan to produce a result. This is done by methods like Evaluate.
Convenience methods like Eval and EvalStr combine both steps, which is perfectly acceptable for one-off calculations but inefficient for repeated use.
Key Performance Strategies
1. The "Parse-Once, Evaluate-Many" Pattern
This is the most critical optimization for any expression that is executed more than once, especially inside a loop. By parsing the expression string outside the loop and evaluating the resulting Expression object inside the loop, you avoid the redundant cost of parsing the same structure repeatedly. Execution speed can approach that of native compiled code.
2. Zero-Copy Updates with Host Variable Binding
For frequently updated variables, even calling myVar.Value(i) inside a loop has some overhead. For maximum performance, you can bind a uCalc variable directly to a memory address in your host application using an optional parameter in DefineVariable. This creates a zero-copy "live link," allowing the uCalc engine to read from and write to your native variable's memory directly, eliminating all method call overhead for updates.
3. Prefer Specialized, Type-Safe Methods
When possible, use type-specific accessors and evaluation methods. For example:
- Use
ValueInt32(5)instead ofValue("5"). The former is a direct memory write; the latter involves string parsing. - If an expression is guaranteed to return a boolean, use
EvaluateBool()instead ofEvaluate(). This avoids a potential type conversion from boolean to double, making the operation more direct and efficient.
4. Reuse Objects with Reset()
Creating new objects like a Transformer incurs setup costs (memory allocation, copying default token sets, etc.). For repetitive tasks that use the same configuration, it is far more performant to create a single Transformer instance and call Reset() between operations. This clears the transformer's state (input text, matches) but reuses the existing object and its configuration, avoiding repeated setup overhead.
5. Transformer Performance
{@Eval}vs.{@@Eval}: In replacement strings, the static{@Eval}directive is much faster than the dynamic{@@Eval}.{@Eval}parses its expression once when the rule is created.{@@Eval}re-parses its expression every time a match is found. Use{@Eval}whenever the formula is fixed and only the variable values change.TokenTransformervs.ExpressionTransformer: The TokenTransformer is more efficient than the ExpressionTransformer. It is only triggered when a specific token type (TokenType::TokenTransform) is encountered, whereas theExpressionTransformerruns on every single expression passed to the parser.
⚖️ How uCalc Compares: A Performance Perspective
uCalc's architectural model provides significant performance advantages over common alternatives for runtime evaluation.
vs. Scripting
eval()& .NETDataTable.Compute: These tools are notoriously slow because they must re-parse the expression string on every single call. This makes them completely unsuitable for performance-critical loops where uCalc's two-step model excels.vs. C# Expression Trees: Compiling a C#
Expressioninto a delegate provides similar high performance for evaluation. However, building that expression tree from a raw string at runtime is a complex, multi-step process that often requires writing your own parser. uCalc's Parse() method provides a simple, one-step way to get a high-performance compiled object from a string, offering the best of both worlds.