@@ -92,49 +92,6 @@ fn hash_large_data(bencher: Bencher) {
9292 } ) ;
9393}
9494
95- /// Benchmark incremental digest updates (simulating hash_key with many args)
96- #[ divan:: bench]
97- fn digest_incremental_updates ( bencher : Bencher ) {
98- let chunks: Vec < Vec < u8 > > = ( 0 ..100 )
99- . map ( |i| format ! ( "-I/path/to/include/dir{}" , i) . into_bytes ( ) )
100- . collect ( ) ;
101-
102- bencher. bench ( || {
103- let mut digest = Digest :: new ( ) ;
104- for chunk in & chunks {
105- digest. update ( black_box ( chunk) ) ;
106- }
107- black_box ( digest. finish ( ) )
108- } ) ;
109- }
110-
111- /// Benchmark digest with delimiter (used for structured hashing)
112- #[ divan:: bench]
113- fn digest_with_delimiters ( bencher : Bencher ) {
114- let section_data = b"section_content_data_here_with_more_content" ;
115- let delimiter_names: Vec < & [ u8 ] > = vec ! [
116- b"compiler" ,
117- b"language" ,
118- b"args" ,
119- b"env" ,
120- b"output" ,
121- b"extra1" ,
122- b"extra2" ,
123- b"extra3" ,
124- b"extra4" ,
125- b"extra5" ,
126- ] ;
127-
128- bencher. bench ( || {
129- let mut digest = Digest :: new ( ) ;
130- for name in & delimiter_names {
131- digest. delimiter ( name) ;
132- digest. update ( black_box ( section_data) ) ;
133- }
134- black_box ( digest. finish ( ) )
135- } ) ;
136- }
137-
13895// =============================================================================
13996// Time Macro Finder Benchmarks
14097// =============================================================================
@@ -379,7 +336,9 @@ fn cache_entry_create_small(bencher: Bencher) {
379336 bencher. bench ( || {
380337 let mut entry = CacheWrite :: new ( ) ;
381338 let mut cursor = Cursor :: new ( black_box ( & obj_data) ) ;
382- entry. put_object ( "output.o" , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
339+ entry
340+ . put_object ( "output.o" , & mut cursor, Some ( 0o644 ) )
341+ . unwrap ( ) ;
383342 entry. put_stdout ( black_box ( stdout_data) ) . unwrap ( ) ;
384343 entry. put_stderr ( black_box ( stderr_data) ) . unwrap ( ) ;
385344 black_box ( entry)
@@ -396,7 +355,9 @@ fn cache_entry_create_large(bencher: Bencher) {
396355 bencher. bench ( || {
397356 let mut entry = CacheWrite :: new ( ) ;
398357 let mut cursor = Cursor :: new ( black_box ( & obj_data) ) ;
399- entry. put_object ( "output.o" , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
358+ entry
359+ . put_object ( "output.o" , & mut cursor, Some ( 0o644 ) )
360+ . unwrap ( ) ;
400361 entry. put_stdout ( black_box ( stdout_data) ) . unwrap ( ) ;
401362 entry. put_stderr ( black_box ( stderr_data) ) . unwrap ( ) ;
402363 black_box ( entry)
@@ -412,7 +373,9 @@ fn cache_entry_roundtrip_small(bencher: Bencher) {
412373 // Create and finish entry
413374 let mut entry = CacheWrite :: new ( ) ;
414375 let mut cursor = Cursor :: new ( black_box ( & obj_data) ) ;
415- entry. put_object ( "output.o" , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
376+ entry
377+ . put_object ( "output.o" , & mut cursor, Some ( 0o644 ) )
378+ . unwrap ( ) ;
416379 entry. put_stdout ( b"success\n " ) . unwrap ( ) ;
417380 let bytes = entry. finish ( ) . unwrap ( ) ;
418381
@@ -435,7 +398,9 @@ fn cache_entry_roundtrip_large(bencher: Bencher) {
435398 // Create and finish entry
436399 let mut entry = CacheWrite :: new ( ) ;
437400 let mut cursor = Cursor :: new ( black_box ( & obj_data) ) ;
438- entry. put_object ( "output.o" , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
401+ entry
402+ . put_object ( "output.o" , & mut cursor, Some ( 0o644 ) )
403+ . unwrap ( ) ;
439404 entry. put_stdout ( b"compilation successful\n " ) . unwrap ( ) ;
440405 entry. put_stderr ( b"warning: something\n " ) . unwrap ( ) ;
441406 let bytes = entry. finish ( ) . unwrap ( ) ;
@@ -462,7 +427,9 @@ fn cache_entry_batch_create(bencher: Bencher) {
462427 for i in 0 ..num_files {
463428 let mut entry = CacheWrite :: new ( ) ;
464429 let mut cursor = Cursor :: new ( black_box ( & obj_data) ) ;
465- entry. put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
430+ entry
431+ . put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) )
432+ . unwrap ( ) ;
466433 entry. put_stdout ( b"success\n " ) . unwrap ( ) ;
467434 let _bytes = entry. finish ( ) . unwrap ( ) ;
468435 black_box ( _bytes) ;
@@ -484,26 +451,30 @@ fn cache_entry_batch_roundtrip(bencher: Bencher) {
484451 for i in 0 ..num_files {
485452 let mut entry = CacheWrite :: new ( ) ;
486453 let mut cursor = Cursor :: new ( black_box ( & obj_data) ) ;
487- entry. put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
454+ entry
455+ . put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) )
456+ . unwrap ( ) ;
488457 entry. put_stdout ( b"success\n " ) . unwrap ( ) ;
489- b"-fPIC" . to_vec ( ) ,
490- b"-fstack-protector-strong" . to_vec ( ) ,
491- b"-march=native" . to_vec ( ) ,
492- b"-mtune=native" . to_vec ( ) ,
493- b"-fno-exceptions" . to_vec ( ) ,
494- b"-fno-rtti" . to_vec ( ) ,
495- b"-fvisibility=hidden" . to_vec ( ) ,
496- ] ;
458+ entries_data. push ( entry. finish ( ) . unwrap ( ) ) ;
459+ }
497460
498- bencher. bench ( || {
499- let mut digest = Digest :: new ( ) ;
500- for flag in & flags {
501- digest. update ( black_box ( flag) ) ;
461+ // Cache hit: read all entries back
462+ for ( i, bytes) in entries_data. into_iter ( ) . enumerate ( ) {
463+ let cursor = Cursor :: new ( bytes) ;
464+ let mut reader = CacheRead :: from ( cursor) . unwrap ( ) ;
465+ let mut output = Vec :: new ( ) ;
466+ reader
467+ . get_object ( & format ! ( "output{}.o" , i) , & mut output)
468+ . unwrap ( ) ;
469+ black_box ( output) ;
502470 }
503- black_box ( digest. finish ( ) )
504471 } ) ;
505472}
506473
474+ // =============================================================================
475+ // Hash Computation Scenarios Benchmarks
476+ // =============================================================================
477+
507478/// Benchmark hashing typical header file content
508479#[ divan:: bench]
509480fn hash_header_file ( bencher : Bencher ) {
@@ -559,7 +530,9 @@ fn build_workflow_initial(bencher: Bencher) {
559530 // Create cache entry
560531 let mut entry = CacheWrite :: new ( ) ;
561532 let mut cursor = Cursor :: new ( black_box ( & obj_data) ) ;
562- entry. put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
533+ entry
534+ . put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) )
535+ . unwrap ( ) ;
563536 entry. put_stdout ( b"success\n " ) . unwrap ( ) ;
564537 let _bytes = entry. finish ( ) . unwrap ( ) ;
565538 black_box ( _bytes) ;
@@ -579,7 +552,9 @@ fn build_workflow_rebuild(bencher: Bencher) {
579552 . map ( |i| {
580553 let mut entry = CacheWrite :: new ( ) ;
581554 let mut cursor = Cursor :: new ( & obj_data) ;
582- entry. put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
555+ entry
556+ . put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) )
557+ . unwrap ( ) ;
583558 entry. put_stdout ( b"success\n " ) . unwrap ( ) ;
584559 entry. finish ( ) . unwrap ( )
585560 } )
@@ -598,7 +573,9 @@ fn build_workflow_rebuild(bencher: Bencher) {
598573 let cursor = Cursor :: new ( cached_bytes. clone ( ) ) ;
599574 let mut reader = CacheRead :: from ( cursor) . unwrap ( ) ;
600575 let mut output = Vec :: new ( ) ;
601- reader. get_object ( & format ! ( "output{}.o" , i) , & mut output) . unwrap ( ) ;
576+ reader
577+ . get_object ( & format ! ( "output{}.o" , i) , & mut output)
578+ . unwrap ( ) ;
602579 black_box ( output) ;
603580 }
604581 } ) ;
@@ -616,7 +593,9 @@ fn build_workflow_incremental(bencher: Bencher) {
616593 . map ( |i| {
617594 let mut entry = CacheWrite :: new ( ) ;
618595 let mut cursor = Cursor :: new ( & obj_data) ;
619- entry. put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
596+ entry
597+ . put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) )
598+ . unwrap ( ) ;
620599 entry. put_stdout ( b"success\n " ) . unwrap ( ) ;
621600 entry. finish ( ) . unwrap ( )
622601 } )
@@ -635,7 +614,9 @@ fn build_workflow_incremental(bencher: Bencher) {
635614 // Cache miss: recompile
636615 let mut entry = CacheWrite :: new ( ) ;
637616 let mut cursor = Cursor :: new ( black_box ( & obj_data) ) ;
638- entry. put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
617+ entry
618+ . put_object ( & format ! ( "output{}.o" , i) , & mut cursor, Some ( 0o644 ) )
619+ . unwrap ( ) ;
639620 entry. put_stdout ( b"success\n " ) . unwrap ( ) ;
640621 let _bytes = entry. finish ( ) . unwrap ( ) ;
641622 black_box ( _bytes) ;
@@ -644,7 +625,9 @@ fn build_workflow_incremental(bencher: Bencher) {
644625 let cursor = Cursor :: new ( cache_entry. clone ( ) ) ;
645626 let mut reader = CacheRead :: from ( cursor) . unwrap ( ) ;
646627 let mut output = Vec :: new ( ) ;
647- reader. get_object ( & format ! ( "output{}.o" , i) , & mut output) . unwrap ( ) ;
628+ reader
629+ . get_object ( & format ! ( "output{}.o" , i) , & mut output)
630+ . unwrap ( ) ;
648631 black_box ( output) ;
649632 }
650633 }
@@ -684,7 +667,9 @@ fn compression_high_compressibility(bencher: Bencher) {
684667 bencher. bench ( || {
685668 let mut entry = CacheWrite :: new ( ) ;
686669 let mut cursor = Cursor :: new ( black_box ( & obj_data) ) ;
687- entry. put_object ( "output.o" , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
670+ entry
671+ . put_object ( "output.o" , & mut cursor, Some ( 0o644 ) )
672+ . unwrap ( ) ;
688673 entry. put_stdout ( b"success\n " ) . unwrap ( ) ;
689674 black_box ( entry. finish ( ) . unwrap ( ) )
690675 } ) ;
@@ -698,7 +683,9 @@ fn compression_low_compressibility(bencher: Bencher) {
698683 bencher. bench ( || {
699684 let mut entry = CacheWrite :: new ( ) ;
700685 let mut cursor = Cursor :: new ( black_box ( & obj_data) ) ;
701- entry. put_object ( "output.o" , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
686+ entry
687+ . put_object ( "output.o" , & mut cursor, Some ( 0o644 ) )
688+ . unwrap ( ) ;
702689 entry. put_stdout ( b"success\n " ) . unwrap ( ) ;
703690 black_box ( entry. finish ( ) . unwrap ( ) )
704691 } ) ;
@@ -712,7 +699,9 @@ fn decompression_high_ratio(bencher: Bencher) {
712699 // Pre-create compressed entry
713700 let mut entry = CacheWrite :: new ( ) ;
714701 let mut cursor = Cursor :: new ( & obj_data) ;
715- entry. put_object ( "output.o" , & mut cursor, Some ( 0o644 ) ) . unwrap ( ) ;
702+ entry
703+ . put_object ( "output.o" , & mut cursor, Some ( 0o644 ) )
704+ . unwrap ( ) ;
716705 let compressed = entry. finish ( ) . unwrap ( ) ;
717706
718707 bencher. bench ( || {
@@ -729,6 +718,34 @@ fn decompression_high_ratio(bencher: Bencher) {
729718fn decompression_low_ratio ( bencher : Bencher ) {
730719 let obj_data = generate_incompressible_data ( 500 * 1024 ) ;
731720
721+ // Pre-create compressed entry
722+ let mut entry = CacheWrite :: new ( ) ;
723+ let mut cursor = Cursor :: new ( & obj_data) ;
724+ entry
725+ . put_object ( "output.o" , & mut cursor, Some ( 0o644 ) )
726+ . unwrap ( ) ;
727+ let compressed = entry. finish ( ) . unwrap ( ) ;
728+
729+ bencher. bench ( || {
730+ let cursor = Cursor :: new ( black_box ( compressed. clone ( ) ) ) ;
731+ let mut reader = CacheRead :: from ( cursor) . unwrap ( ) ;
732+ let mut output = Vec :: new ( ) ;
733+ reader. get_object ( "output.o" , & mut output) . unwrap ( ) ;
734+ black_box ( output)
735+ } ) ;
736+ }
737+
738+ // =============================================================================
739+ // Realistic LRU Cache Access Pattern Benchmarks
740+ // =============================================================================
741+
742+ /// Benchmark LRU cache with hot/cold access pattern (80/20 rule)
743+ #[ divan:: bench]
744+ fn lru_hotcold_access_pattern ( bencher : Bencher ) {
745+ let total_keys = 1000 ;
746+ let hot_keys = 200 ; // 20% of keys get 80% of accesses
747+
748+ bencher
732749 . with_inputs ( || {
733750 let mut cache: LruCache < String , u64 > = LruCache :: new ( ( total_keys * 2 ) as u64 ) ;
734751 // Populate cache
@@ -754,32 +771,6 @@ fn decompression_low_ratio(bencher: Bencher) {
754771 } ) ;
755772}
756773
757- /// Benchmark LRU cache with working set pattern (repeated access to same subset)
758- #[ divan:: bench]
759- fn lru_working_set_pattern ( bencher : Bencher ) {
760- let total_keys = 2000 ;
761- let working_set_size = 100 ;
762-
763- bencher
764- . with_inputs ( || {
765- let mut cache: LruCache < String , u64 > = LruCache :: new ( ( total_keys * 2 ) as u64 ) ;
766- for i in 0 ..total_keys {
767- cache. insert ( format ! ( "key_{:08x}" , i) , i as u64 ) ;
768- }
769- let keys: Vec < String > = ( 0 ..total_keys) . map ( |i| format ! ( "key_{:08x}" , i) ) . collect ( ) ;
770- ( cache, keys)
771- } )
772- . bench_values ( |( mut cache, keys) | {
773- // Access working set repeatedly
774- for _ in 0 ..10 {
775- for key in keys. iter ( ) . take ( working_set_size) {
776- black_box ( cache. get ( key) ) ;
777- }
778- }
779- black_box ( cache)
780- } ) ;
781- }
782-
783774/// Benchmark LRU cache with sequential scan pattern
784775#[ divan:: bench]
785776fn lru_sequential_scan_pattern ( bencher : Bencher ) {
0 commit comments