/
nv-lang
/
nova
Обзор
Документация
Войти
/
nv-lang
/
nova
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
std/src/bench.nv
114 строк
5 KB
Evgeniy Golovin
docs(endocs): root — translate bench, sort, reflect /// docs to English
01 авг 2026, 02:53
01 авг 2026, 02:53
2d8be0e
Код
Авторство
О чём код?
// std/bench.nv — Plan 57 benchmark DSL prelude. // // **NOT auto-gen.** Этот модуль документирует hard-coded namespace `bench.*` // dispatched в codegen (как `gc.*` из std/runtime/gc.nv). // // `bench` — uniqueness: **lowercase namespace** (не type) для consistency с // прецедентами в других языках: // - Rust: `criterion::black_box(...)` // - Go: `b.SetBytes(...)`, `b.ResetTimer()`, `b.N` // - Swift: `XCTMeasure.measure { ... }` // // Видимость: prelude в `bench { ... }` блоках. Технически доступен и из // обычных функций — `bench.opaque(v)` работает как identity (black-box // barrier), `bench.iterations()` вне measure-блока возвращает 0. // // Использование внутри bench DSL: // // bench "parse 1k lines" { // let src = generate_source(1000) // measure { // bench.opaque(parse(src)) // } // } // // bench "hashmap insert N=10k" { // let mut m = HashMap[int, int].new() // measure { // let n = bench.iterations() // for i in 0..n { m.insert(i, i) } // bench.elements(n) // } // } // // bench "read buffer 4096 bytes" { // let buf = make_buffer(4096) // measure { // process(bench.opaque(buf)) // bench.bytes(4096) // → throughput per-second в JSON output // } // } // // ────────────────────────────────────────────────────────────────────────── // Источник истины для type-checker'а и codegen. // ────────────────────────────────────────────────────────────────────────── // // Эти `external fn` объявления — **единственный source of truth**, и для // type-checker'а (обычный `import`), и для codegen: c-имя (`nova_bench_*`, // включая renamed `bytes`→`set_throughput_bytes` и т.п.) приходит через // `ExternalRegistry::NAMESPACE_OVERRIDES` (compiler-codegen/src/codegen/ // external_registry.rs) — этот файл embedded builtin source, ручной // синхронизации с emit_c.rs больше не требуется ([M-compiler-nv-porting- // wave] item B1, 2026-07-07). Исключение — `opaque[T]`: класс C // compiler intrinsic (black-box barrier), permanently hardcoded в // emit_c.rs (не registry-driven — fn-level generic `T` не резолвится // type_ref_to_c, и сама anti-optimization emission — не C-function call). module std.bench // ─── bench namespace ──────────────────────────────────────────────────── /// Black-box barrier — prevents dead-code elimination in benchmarks. /// Analogue of Criterion `hint::black_box`, Go `runtime.KeepAlive`. Zero runtime cost. #stable(since = "0.1") export extern "nova" fn bench.opaque[T](v T) -> T /// Current iters_per_sample (adaptive sampling). For manual batch-loops /// `for i in 0..bench.iterations()`. Outside a measure-block → 0. #stable(since = "0.1") export extern "nova" fn bench.iterations() -> int /// Reset the sample timer to now. To exclude setup code from the timing window. /// Analogue of Go `b.ResetTimer()`. #stable(since = "0.1") export extern "nova" fn bench.reset_timer() -> () /// Throughput annotation: bytes per iter. The CLI computes MB/s. Analogue of Go `b.SetBytes`. #stable(since = "0.1") export extern "nova" fn bench.bytes(n int) -> () /// Throughput annotation: elements per iter. The CLI computes elem/s. Analogue of /// Criterion `Throughput::Elements`. #stable(since = "0.1") export extern "nova" fn bench.elements(n int) -> () /// Snapshot total allocs since program start. The CLI computes per-iter /// alloc count = (post - pre) / total_iters. #stable(since = "0.1") export extern "nova" fn bench.allocs() -> int /// High-resolution monotonic timer in ns. libuv `uv_hrtime` under NOVA_USE_LIBUV, /// otherwise platform-native (QPC / mach_absolute_time / CLOCK_MONOTONIC_RAW). #stable(since = "0.1") export extern "nova" fn bench.now_ns() -> int /// Plan 57.G.5 — Custom metric value. Each call emits ONE sample; /// the CLI aggregates all calls per-bench → JSON `custom_metrics[]` field /// with count/min/max/sum/median. /// /// `name` — a short identifier (e.g. "cache_hits", "lock_contention_ms"), /// `value` — an int value, `unit` — a short text suffix for display. /// Use case: domain metrics not covered built-in (throughput/allocs/ /// cpu_instr); closes the biggest gap vs Go `b.ReportMetric`. /// /// Subtlety: called inside the `measure {}` body → one call per iteration. /// With iters_per_sample=100, samples_count=30 → 3000 metric samples total. /// For a per-sample-end metric: call after the inner loop: /// measure { /// let n = bench.iterations() /// let mut hits = 0 /// for i in 0..n { hits = hits + workload(i) } /// bench.metric("hits_per_sample", hits, "count") // 1 call/sample /// } #stable(since = "0.1") export extern "nova" fn bench.metric(name str, value int, unit str) -> ()