Rust's new API makes floating point math 4x faster

Faster floating point math with Rust's new API

Rust's new API makes floating point math 4x faster

Rust 1.98 introduces algebraic operators that let the compiler optimize floating point math aggressively, while keeping strict operations for precision-critical code. By using these operators in a pairwise summation algorithm, you can match NumPy's speed and accuracy, and even beat it. The new API also enables SIMD instructions, cutting CPU instructions per value dramatically.

Using algebraic operations enables the compiler to generate code that runs twice as fast on my computer.
  1. 14113

    > Floating point math is often slower than integer math because the compiler is being conservative about how it optimizes your code.

    It's not strictly true to say that it's "being conservative". What is more correct is to say that floating point operations have different semantics to integer operations, and an optimisation that retains the semantics of an expression over integers may not do so when applied to an expression over integers. Hence, it may be possible to apply one optimisation to an integer expression, but applying that to a floating-point expression may result in a different program meaning.

    C/C++ compilers give you a way out of this with the `--ffast-math` flag, which essentially allows compilers to relax the constraints on floating-point optimisation passes.

    For an example of how this works in GCC, take a look here: https://gcc.gnu.org/wiki/FloatingPointMath

  2. GeertB

    Signed integer addition is only associative when overflow is defined to wrap around like unsigned arithmetic. This condition is matched here, because only debug builds panic on overflow. However, it's a bit of a gray area that the article completely ignores.

  3. pjmlp

    Ideally CPython would have a JIT that would be able to do this, depending on the current hardware like other ecosystems, but we are still not there yet.

  4. rob74

    I'm not an expert on floating point math, but the "Does adding a small number do nothing?" example caught my eye, because the numbers used are constants, which are arbitrary precision in some languages (https://stackoverflow.com/questions/57511935/what-is-the-pur...). For instance, Go answers the question with false (but still prints out "1e+16" when you try to print 1e16 + 1): https://go.dev/play/p/mSAktWpCRJA

  5. Asooka

    I like the idea, but I hate how verbose it is. Would be nice if there was also a macro that would transform all arithmetic within a block into algebraic arithmetic. The name is also a bit misleading, as I would expect "alebraic_add" to give an exact algebraic result, but instead it enables optimisations based on associative semantics.

    As a sidenote, if implemented as a macro, e.g.

    fn fast_sum_f64(values: &[f64]) -> f64 {

    let mut total = 0;

    fp_opt!(associative, {

    for value in values {

    total += value;

    }

    });

    return total;

    }

    A question arises what happens when operating on custom types that overload arithmetic operations. I think the cleanest approach here would be to let the custom type define optimised versions, or have another macro that automatically generates them based on the existing ones, i.e. propagate the optimisation flags.

More from this day

2026-08-11