For simple numerical operations, using an entire Symbolica Atom will introduce a large amount of overhead. It should only be used if the expression contains symbols as well. But perhaps I misunderstood the point of the benchmark?
For simple numerical operations, using an entire Symbolica Atom will introduce a large amount of overhead. It should only be used if the expression contains symbols as well. But perhaps I misunderstood the point of the benchmark?
Hyperreal gets performance back through caching observed facts about the numbers it's representing at creation, and through operations, and specializing dispatch for predicates and geometric operations. Using this approach throughout the stack allows us to avoid computing on the full representation or collapsing it into an approximation. Instead asking questions like "do we know if it's definitely zero, definitely not, or unknown?" or "is it rational?" or "does it have a known sign, or unknown?" and so on. Each question specializes dispatch further, and some eliminate the need for it entirely.
Asking questions using the cached facts is approximately as fast as computing with f64s. So we do that whenever possible throughout the stack. But then when you actually need to do the exact computation, hyperreal does that too, and can approximate it out to whatever precision you'd like. f32 and f64 being common, but others being supported as well. The downside is that calculating quickly with them requires this sort specialization, but the work's been done for the geometry functions.
I'll look into DoubleFloat and ErrorPropagatingFloat for benches. I should mention that numerica@128bit beat the other pure rust bignum crates I tested. The benchmarks are mostly just to give me an understanding of the performance shapes of the implementation choices of high precision numeric libraries alongside hyperreal.
It's still possible to approximate them both, and test them against each other, but since the whole architecture is built to reduce, avoid, and cache approximations because they're expensive, it's not the default.
You might find this bit of performance engineering interesting: https://github.com/timschmidt/hyperreal/blob/8a016808f4b0ba3...
The matrix math layer wanted that kind of optimization to avoid worst case operations.