@@ -1934,4 +1934,248 @@ mod tests {
19341934 assert_eq ! ( * ts, 200 ) ;
19351935 assert_eq ! ( m. total_blocks, 5 ) ;
19361936 }
1937+
1938+ // -----------------------------------------------------------------------
1939+ // Benchmarks
1940+ // -----------------------------------------------------------------------
1941+ //
1942+ // Run with: cargo test bench_ -- --nocapture
1943+ // These use std::time::Instant and std::hint::black_box for stable timing.
1944+
1945+ #[ test]
1946+ fn bench_batch_scoring_10k ( ) {
1947+ use std:: time:: Instant ;
1948+ use crate :: tiering:: {
1949+ TierConfig , BlockMeta as TBlockMeta , Tier as TTier ,
1950+ compute_scores_batch, compute_score,
1951+ } ;
1952+
1953+ let cfg = TierConfig :: default ( ) ;
1954+ let metas: Vec < TBlockMeta > = ( 0 ..10_000 ) . map ( |i| {
1955+ TBlockMeta {
1956+ ema_rate : ( i as f32 ) * 0.0001 ,
1957+ access_window : 0x5555_5555_5555_5555 ,
1958+ last_access : 50 + ( i as u64 % 100 ) ,
1959+ access_count : i as u64 ,
1960+ current_tier : TTier :: Tier1 ,
1961+ tier_since : 0 ,
1962+ }
1963+ } ) . collect ( ) ;
1964+
1965+ let iters = 1000 ;
1966+
1967+ // Individual scoring
1968+ let start = Instant :: now ( ) ;
1969+ for _ in 0 ..iters {
1970+ for m in & metas {
1971+ std:: hint:: black_box ( compute_score ( & cfg, 100 , m) ) ;
1972+ }
1973+ }
1974+ let individual = start. elapsed ( ) ;
1975+
1976+ // Batch scoring
1977+ let start = Instant :: now ( ) ;
1978+ for _ in 0 ..iters {
1979+ std:: hint:: black_box ( compute_scores_batch ( & cfg, 100 , & metas) ) ;
1980+ }
1981+ let batch = start. elapsed ( ) ;
1982+
1983+ eprintln ! ( "Individual scoring 10k x {iters}: {:?} ({:.0} ns/block)" ,
1984+ individual, individual. as_nanos( ) as f64 / ( iters * 10_000 ) as f64 ) ;
1985+ eprintln ! ( "Batch scoring 10k x {iters}: {:?} ({:.0} ns/block)" ,
1986+ batch, batch. as_nanos( ) as f64 / ( iters * 10_000 ) as f64 ) ;
1987+ }
1988+
1989+ #[ test]
1990+ fn bench_dequant_5bit_4096 ( ) {
1991+ use std:: time:: Instant ;
1992+
1993+ let data: Vec < f32 > = ( 0 ..4096 ) . map ( |i| ( i as f32 - 2048.0 ) * 0.01 ) . collect ( ) ;
1994+ let ( packed, scale) = quantize_block ( & data, 5 ) ;
1995+ let mut out = vec ! [ 0.0f32 ; 4096 ] ;
1996+
1997+ let iters = 10_000 ;
1998+ let start = Instant :: now ( ) ;
1999+ for _ in 0 ..iters {
2000+ std:: hint:: black_box ( dequantize_block ( & packed, scale, 5 , 4096 , & mut out) ) ;
2001+ }
2002+ let elapsed = start. elapsed ( ) ;
2003+
2004+ let total_bytes = 4096u64 * 4 * iters as u64 ;
2005+ let gbs = total_bytes as f64 / elapsed. as_secs_f64 ( ) / 1e9 ;
2006+ eprintln ! ( "Dequant 5-bit 4096 x {iters}: {:?} ({:.2} GB/s output throughput)" ,
2007+ elapsed, gbs) ;
2008+ }
2009+
2010+ #[ test]
2011+ fn bench_dequant_7bit_4096 ( ) {
2012+ use std:: time:: Instant ;
2013+
2014+ let data: Vec < f32 > = ( 0 ..4096 ) . map ( |i| ( i as f32 - 2048.0 ) * 0.01 ) . collect ( ) ;
2015+ let ( packed, scale) = quantize_block ( & data, 7 ) ;
2016+ let mut out = vec ! [ 0.0f32 ; 4096 ] ;
2017+
2018+ let iters = 10_000 ;
2019+ let start = Instant :: now ( ) ;
2020+ for _ in 0 ..iters {
2021+ std:: hint:: black_box ( dequantize_block ( & packed, scale, 7 , 4096 , & mut out) ) ;
2022+ }
2023+ let elapsed = start. elapsed ( ) ;
2024+
2025+ let total_bytes = 4096u64 * 4 * iters as u64 ;
2026+ let gbs = total_bytes as f64 / elapsed. as_secs_f64 ( ) / 1e9 ;
2027+ eprintln ! ( "Dequant 7-bit 4096 x {iters}: {:?} ({:.2} GB/s output throughput)" ,
2028+ elapsed, gbs) ;
2029+ }
2030+
2031+ #[ test]
2032+ fn bench_quant_5bit_4096 ( ) {
2033+ use std:: time:: Instant ;
2034+
2035+ let data: Vec < f32 > = ( 0 ..4096 ) . map ( |i| ( i as f32 - 2048.0 ) * 0.01 ) . collect ( ) ;
2036+
2037+ let iters = 10_000 ;
2038+ let start = Instant :: now ( ) ;
2039+ for _ in 0 ..iters {
2040+ std:: hint:: black_box ( quantize_block ( & data, 5 ) ) ;
2041+ }
2042+ let elapsed = start. elapsed ( ) ;
2043+
2044+ let total_bytes = 4096u64 * 4 * iters as u64 ;
2045+ let gbs = total_bytes as f64 / elapsed. as_secs_f64 ( ) / 1e9 ;
2046+ eprintln ! ( "Quant 5-bit 4096 x {iters}: {:?} ({:.2} GB/s input throughput)" ,
2047+ elapsed, gbs) ;
2048+ }
2049+
2050+ #[ test]
2051+ fn bench_svd_adaptive_64x64 ( ) {
2052+ use std:: time:: Instant ;
2053+ use crate :: delta:: FactorSet ;
2054+
2055+ let ( rows, cols) = ( 64 , 64 ) ;
2056+ let data: Vec < f32 > = ( 0 ..rows * cols)
2057+ . map ( |i| ( i as f32 * 0.37 ) . sin ( ) + ( i as f32 * 0.73 ) . cos ( ) )
2058+ . collect ( ) ;
2059+
2060+ let iters = 100 ;
2061+ let start = Instant :: now ( ) ;
2062+ for _ in 0 ..iters {
2063+ std:: hint:: black_box (
2064+ FactorSet :: from_data_adaptive ( & data, rows, cols, 16 , 0.05 )
2065+ ) ;
2066+ }
2067+ let elapsed = start. elapsed ( ) ;
2068+
2069+ eprintln ! ( "SVD adaptive 64x64 (max_rank=16, target=0.05) x {iters}: {:?} ({:.2} ms/iter)" ,
2070+ elapsed, elapsed. as_secs_f64( ) * 1000.0 / iters as f64 ) ;
2071+ }
2072+
2073+ #[ test]
2074+ fn bench_format_report ( ) {
2075+ use std:: time:: Instant ;
2076+ use crate :: metrics:: StoreMetrics ;
2077+
2078+ let m = StoreMetrics {
2079+ total_blocks : 10_000 ,
2080+ tier0_blocks : 500 ,
2081+ tier1_blocks : 4000 ,
2082+ tier2_blocks : 3500 ,
2083+ tier3_blocks : 2000 ,
2084+ tier1_bytes : 4_000_000 ,
2085+ tier2_bytes : 2_500_000 ,
2086+ tier3_bytes : 750_000 ,
2087+ total_reads : 1_000_000 ,
2088+ total_writes : 500_000 ,
2089+ total_evictions : 5000 ,
2090+ total_upgrades : 12_000 ,
2091+ total_downgrades : 8000 ,
2092+ total_reconstructions : 200 ,
2093+ total_checksum_failures : 0 ,
2094+ total_compactions : 150 ,
2095+ tier_flips_last_minute : 0.023 ,
2096+ avg_score_tier1 : 0.85 ,
2097+ avg_score_tier2 : 0.45 ,
2098+ avg_score_tier3 : 0.12 ,
2099+ } ;
2100+
2101+ let iters = 10_000 ;
2102+ let start = Instant :: now ( ) ;
2103+ for _ in 0 ..iters {
2104+ std:: hint:: black_box ( m. format_report ( ) ) ;
2105+ }
2106+ let elapsed = start. elapsed ( ) ;
2107+
2108+ eprintln ! ( "format_report x {iters}: {:?} ({:.0} ns/call)" ,
2109+ elapsed, elapsed. as_nanos( ) as f64 / iters as f64 ) ;
2110+ }
2111+
2112+ #[ test]
2113+ fn bench_format_json ( ) {
2114+ use std:: time:: Instant ;
2115+ use crate :: metrics:: StoreMetrics ;
2116+
2117+ let m = StoreMetrics {
2118+ total_blocks : 10_000 ,
2119+ tier0_blocks : 500 ,
2120+ tier1_blocks : 4000 ,
2121+ tier2_blocks : 3500 ,
2122+ tier3_blocks : 2000 ,
2123+ tier1_bytes : 4_000_000 ,
2124+ tier2_bytes : 2_500_000 ,
2125+ tier3_bytes : 750_000 ,
2126+ total_reads : 1_000_000 ,
2127+ total_writes : 500_000 ,
2128+ total_evictions : 5000 ,
2129+ total_upgrades : 12_000 ,
2130+ total_downgrades : 8000 ,
2131+ total_reconstructions : 200 ,
2132+ total_checksum_failures : 0 ,
2133+ total_compactions : 150 ,
2134+ tier_flips_last_minute : 0.023 ,
2135+ avg_score_tier1 : 0.85 ,
2136+ avg_score_tier2 : 0.45 ,
2137+ avg_score_tier3 : 0.12 ,
2138+ } ;
2139+
2140+ let iters = 10_000 ;
2141+ let start = Instant :: now ( ) ;
2142+ for _ in 0 ..iters {
2143+ std:: hint:: black_box ( m. format_json ( ) ) ;
2144+ }
2145+ let elapsed = start. elapsed ( ) ;
2146+
2147+ eprintln ! ( "format_json x {iters}: {:?} ({:.0} ns/call)" ,
2148+ elapsed, elapsed. as_nanos( ) as f64 / iters as f64 ) ;
2149+ }
2150+
2151+ #[ test]
2152+ fn bench_metrics_series_trend_100 ( ) {
2153+ use std:: time:: Instant ;
2154+ use crate :: metrics:: { StoreMetrics , MetricsSeries } ;
2155+
2156+ let mut series = MetricsSeries :: new ( 256 ) ;
2157+ for i in 0 ..100u64 {
2158+ series. record ( i, StoreMetrics {
2159+ total_blocks : 1000 + i,
2160+ tier1_blocks : 400 + i % 50 ,
2161+ tier2_blocks : 350 ,
2162+ tier3_blocks : 250 ,
2163+ tier1_bytes : 400_000 + i * 100 ,
2164+ tier2_bytes : 250_000 ,
2165+ tier3_bytes : 75_000 ,
2166+ total_evictions : i * 3 ,
2167+ ..Default :: default ( )
2168+ } ) ;
2169+ }
2170+
2171+ let iters = 10_000 ;
2172+ let start = Instant :: now ( ) ;
2173+ for _ in 0 ..iters {
2174+ std:: hint:: black_box ( series. trend ( ) ) ;
2175+ }
2176+ let elapsed = start. elapsed ( ) ;
2177+
2178+ eprintln ! ( "MetricsSeries trend (100 snapshots) x {iters}: {:?} ({:.0} ns/call)" ,
2179+ elapsed, elapsed. as_nanos( ) as f64 / iters as f64 ) ;
2180+ }
19372181}
0 commit comments