uCalc API Version: 2.1.3-preview.2 Released: 6/16/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 of Value("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 of Evaluate(). 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.
  • TokenTransformer vs. ExpressionTransformer: The TokenTransformer is more efficient than the ExpressionTransformer. It is only triggered when a specific token type (TokenType::TokenTransform) is encountered, whereas the ExpressionTransformer runs 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() & .NET DataTable.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# Expression into 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.

Examples