dtolnay / ryu

Fast floating point to string conversion
Apache License 2.0
606 stars 27 forks source link

[investigation] why in debug mode ryu is slower ? #49

Closed alexzanderr closed 1 year ago

alexzanderr commented 1 year ago

hello.

i have a small simple example of benching with the std::time::Instant and the perf of ryu in debug mode is slower than std, but in release is faster.

why? what am i missing? what am i doing wrong (im pretty sure im doing something wrong)

use std::time::Instant;
use std::fmt::Write;

use ryu::Buffer as FastFloatBuffer;

fn ryu_formatter(
    numbers: &[f64],
    iterations: i32,
) {
    let _now = Instant::now();

    let mut ffb = FastFloatBuffer::new();

    for num in numbers {
        for index in 0..iterations {
            let printed = ffb.format_finite(*num);
            // println!("printed: {printed}");
        }
    }

    let _elapsed = _now.elapsed();
    println!("RYU:         {} secs", _elapsed.as_secs_f64());
}

fn std_format_macro(
    numbers: &[f64],
    iterations: i32,
) {
    let _now = Instant::now();

    let mut buffer = String::new();
    for num in numbers {
        for index in 0..iterations {
            let printed = format!("{}", *num);
        }
    }

    let _elapsed = _now.elapsed();
    println!("std format!: {} secs", _elapsed.as_secs_f64());
}

fn std_write_macro(
    numbers: &[f64],
    iterations: i32,
) {
    let _now = Instant::now();

    let mut buffer = String::new();
    for num in numbers {
        for index in 0..iterations {
            std::write!(&mut buffer, "{}", *num);
        }
    }

    let _elapsed = _now.elapsed();
    println!("std write!:  {} secs", _elapsed.as_secs_f64());
}

fn main() {
    let numbers = [1.0, 1.2, 1.3, 1.45, 4.545, 677.123];
    let iterations = 1000000;

    ryu_formatter(&numbers, iterations);
    std_format_macro(&numbers, iterations);
    std_write_macro(&numbers, iterations);
}

i know the example is not that advanced and doesnt cover all the cases, but it was something made up really quick to try out ryu crate

running in debug mode: ryu is slower

RYU:         3.606432407 secs
std format!: 1.298629963 secs
std write!:  1.406031308 secs

running in release mode: ryu is faster (which, ofc, is good)

RYU:         0.328770684 secs
std format!: 0.687923447 secs
std write!:  0.547766281 secs

my question is why ryu in debug mode is slower ?

or a better question would be: is ryu designed only to be faster in release mode ?

dtolnay commented 1 year ago

Debug mode and release mode Rust programs use the same standard library build. There is only one standard library and it is release mode. So you are not actually comparing against a debug mode std::fmt implementation. That would be way slower.

alexzanderr commented 1 year ago

Debug mode and release mode Rust programs use the same standard library build.

because std is already compiled right? (its inside the compiler from what i know and i guess already in release mode)

yeah, you answered here: There is only one standard library and it is release mode

So you are not actually comparing against a debug mode std::fmt implementation. That would be way slower.

ok, nice, so ryu is faster in both cases

thanks for response!

alexzanderr commented 1 year ago

when you benched this crate, did you compare it with debug mode std::fmt or you benched everything in release mode ?