MathCore is designed to be fast for a symbolic math library — it uses LTO in release builds, delegates matrix operations to nalgebra, and provides optional rayon-based parallelism for batch workloads. This page covers the key knobs available to you, explains the cost of common operations, and shows patterns that avoid unnecessary work.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Nonanti/mathcore/llms.txt
Use this file to discover all available pages before exploring further.
Release Build Profile
MathCore’sCargo.toml ships with an optimised release profile that is automatically used when you run cargo build --release or cargo bench:
| Setting | Value | Effect |
|---|---|---|
lto | true | Link-time optimisation — the compiler can inline and prune across crate boundaries |
codegen-units | 1 | Single codegen unit — slower compile, but enables whole-crate optimisation |
opt-level | 3 | Maximum LLVM optimisation level |
LTO is the most impactful of these three settings for MathCore. Because the library relies heavily on small functions called in tight loops (expression tree traversal, operator dispatch), LTO allows the compiler to inline them away and produce substantially tighter machine code.
lto in your workspace root will take precedence.
Operation Cost Estimates
Based on the benchmark suite inbenches/expression_bench.rs and the numbers documented in the README:
| Operation | Approximate cost |
|---|---|
| Expression parsing | ~1 μs |
| Symbolic differentiation (polynomial) | ~10 μs |
| Symbolic integration (polynomial) | ~10–20 μs |
| Numeric evaluation (pre-parsed) | sub-μs |
| Matrix multiply (via nalgebra) | depends on size and BLAS availability |
| Arbitrary-precision arithmetic | varies with digit count |
Matrix operations delegate entirely to nalgebra, which uses BLAS when available on the platform. If your workload is matrix-heavy, linking an optimised BLAS implementation (such as OpenBLAS or MKL) will have a far larger impact than any MathCore-specific tuning.
Parse Once, Evaluate Many Times
The single most impactful optimisation available to application code is to separate parsing from evaluation.MathCore::parse() returns an Expr — the parsed expression tree — which can then be passed to the engine repeatedly without re-parsing the string.
math.evaluate_with_vars(expression_str, &vars) in the loop, which re-parses the string on every iteration.
Enable the parallel Feature for Batch Operations
When you need to evaluate the same expression over a large set of inputs (e.g., building a lookup table, computing a loss surface, or processing sensor data), enable the parallel feature to unlock rayon-based parallelism:
parallel requires std. It will not compile for no_std targets.Prefer f64 Arithmetic for Performance-Sensitive Paths
MathCore supports arbitrary-precision rational arithmetic through num-bigint and num-rational, which is useful for exact results but comes with a significant runtime cost. For performance-sensitive code, stick with the default f64-backed Expr::Number path:
- Use
math.calculate()ormath.evaluate_with_vars()for numeric work — these returnf64directly. - Avoid constructing
PrecisionNumberorBigRationalvalues in hot loops unless exact arithmetic is actually required.
Use MathCore::calculate() for Numeric-Only Expressions
For expressions that contain no variables (pure constant arithmetic), MathCore::calculate() is the most direct path to a result. It parses, evaluates, and returns f64 in one call, without constructing a variable map:
evaluate_with_vars for expressions that actually require variable substitution.
Running the Benchmarks
The full benchmark suite lives inbenches/expression_bench.rs and covers parsing, evaluation, differentiation, integration, equation solving, matrix operations, ODEs, and arbitrary-precision arithmetic. Run it with:
target/criterion/. The bench profile inherits from release, so LTO and opt-level = 3 apply automatically:
Summary of Recommendations
| Recommendation | Impact |
|---|---|
Always use --release (or cargo bench) for timing | High — debug builds are 10–100× slower |
| Parse once, evaluate in a loop | High — eliminates repeated string parsing |
Enable parallel for large batch evaluations | Medium — depends on input size and core count |
| Link an optimised BLAS for matrix-heavy code | High for matrices, zero for scalar math |
Use f64 paths instead of arbitrary precision | High — BigInt ops are orders of magnitude slower |
Prefer calculate() over evaluate() for constant expressions | Low — minor, but cleaner code |
