Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-map3d-flight/benches/heavy_daycycle.rs

//! **HEAVY day-cycle benchmark** — the time-of-day sun/sky driver evaluated at full
//! rate over a dense hour + season sweep (the Bencher LAW: bench the PARTS, then the
//! rollup). Each `sun_sky` call reuses the landed `Atmosphere` transmittance LUT, so
//! this measures the per-frame cost of animating the whole sky.
//!
//! Steps benched, each with an evaluations/sec throughput:
//! - `solar_angles`  — the astronomy (declination + hour angle → elevation/azimuth)
//! - `sun_dir`       — angles → unit surface→sun direction
//! - `sun_sky_clear` — the FULL SunSky (sun colour/intensity + atmosphere sky tint)
//! - `sun_sky_overcast` — the same with the overcast weather blend on top
//!
//! Sweep size is `MAP3D_FLIGHT_DAYCYCLE_N` (default 100000 queries). Run:
//!   CARGO_TARGET_DIR=/mnt/work4t/cargo-target/facett-map3d-flight \
//!   cargo bench -p facett-map3d-flight --bench heavy_daycycle

use std::hint::black_box;

use criterion::{Criterion, Throughput, criterion_group, criterion_main};

use facett_map3d_flight::daycycle::{DayCycle, Weather, solar_angles, sun_dir};
use facett_map3d_flight::Atmosphere;

fn sweep_n() -> usize {
    std::env::var("MAP3D_FLIGHT_DAYCYCLE_N").ok().and_then(|v| v.parse().ok()).unwrap_or(100_000)
}

/// A deterministic `(latitude, day_of_year, hour)` query cloud over the year + globe.
fn queries(n: usize) -> Vec<(f32, u32, f32)> {
    (0..n)
        .map(|i| {
            let f = i as f32 / n as f32;
            let lat = -60.0 + 120.0 * ((i * 2654435761usize) % 1000) as f32 / 1000.0;
            let doy = ((i * 40503) % 365) as u32;
            let hour = 24.0 * f;
            (lat, doy, hour)
        })
        .collect()
}

fn bench_daycycle(c: &mut Criterion) {
    let n = sweep_n();
    let q = queries(n);
    let atmos = Atmosphere::earth();

    {
        let mut g = c.benchmark_group("solar_angles");
        g.throughput(Throughput::Elements(n as u64));
        g.bench_function("astronomy", |b| {
            b.iter(|| {
                let mut acc = 0.0f32;
                for &(lat, doy, hour) in black_box(&q) {
                    acc += solar_angles(lat, doy, hour).elevation_rad;
                }
                black_box(acc)
            });
        });
        g.finish();
    }

    {
        let mut g = c.benchmark_group("sun_dir");
        g.throughput(Throughput::Elements(n as u64));
        g.bench_function("dir", |b| {
            b.iter(|| {
                let mut acc = 0.0f32;
                for &(lat, doy, hour) in black_box(&q) {
                    acc += sun_dir(solar_angles(lat, doy, hour))[1];
                }
                black_box(acc)
            });
        });
        g.finish();
    }

    for (label, weather) in [("sun_sky_clear", Weather::clear()), ("sun_sky_overcast", Weather::overcast())] {
        let mut g = c.benchmark_group(label);
        g.throughput(Throughput::Elements(n as u64));
        g.bench_function("full", |b| {
            b.iter(|| {
                let mut acc = 0.0f32;
                for &(lat, doy, hour) in black_box(&q) {
                    let dc = DayCycle { latitude_deg: lat, day_of_year: doy, weather, exposure: 12.0 };
                    let (s, _) = dc.sun_sky(hour, black_box(&atmos), 1500.0);
                    acc += s.sun_intensity + s.sky_color[2];
                }
                black_box(acc)
            });
        });
        g.finish();
    }

    eprintln!("[heavy_daycycle] {n} time-of-day queries per iteration (lat × season × hour sweep)");
}

criterion_group!(benches, bench_daycycle);
criterion_main!(benches);