-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcache_performance_analysis.rs
More file actions
127 lines (100 loc) · 3.77 KB
/
cache_performance_analysis.rs
File metadata and controls
127 lines (100 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use std::time::Instant;
use quickleaf::Cache;
fn main() {
println!("Testing real-world cache performance scenarios...");
// Test 1: Random access patterns (where prefetch should hurt)
test_random_access();
// Test 2: Sequential access patterns (where prefetch should help)
test_sequential_access();
// Test 3: Large cache list operations
test_large_list_operations();
// Test 4: Cleanup operations with many expired items
test_cleanup_operations();
}
fn test_random_access() {
println!("\n--- Random Access Test ---");
let mut cache = Cache::new(10000);
// Pre-populate with 10k items
for i in 0..10000 {
cache.insert(format!("item{:05}", i), format!("value{}", i));
}
// Random access pattern
let mut rng_seed = 42u64;
let iterations = 100000;
let start = Instant::now();
for _ in 0..iterations {
// Simple LCG for reproducible "random" numbers
rng_seed = rng_seed.wrapping_mul(1664525).wrapping_add(1013904223);
let index = (rng_seed % 10000) as usize;
let key = format!("item{:05}", index);
std::hint::black_box(cache.get(&key));
}
let duration = start.elapsed();
println!("Random access ({} ops): {:?}", iterations, duration);
println!("Average per access: {:?}", duration / iterations);
}
fn test_sequential_access() {
println!("\n--- Sequential Access Test ---");
let mut cache = Cache::new(10000);
// Pre-populate
for i in 0..10000 {
cache.insert(format!("seq{:05}", i), format!("value{}", i));
}
let iterations = 10;
let start = Instant::now();
for _ in 0..iterations {
// Sequential access through the entire cache
for i in 0..10000 {
let key = format!("seq{:05}", i);
std::hint::black_box(cache.get(&key));
}
}
let duration = start.elapsed();
println!("Sequential access ({} full sweeps): {:?}", iterations, duration);
println!("Average per access: {:?}", duration / (iterations * 10000));
}
fn test_large_list_operations() {
println!("\n--- Large List Operations Test ---");
let mut cache = Cache::new(50000);
// Pre-populate with 50k items
for i in 0..50000 {
cache.insert(format!("list{:06}", i), i);
}
let iterations = 100;
let start = Instant::now();
for _ in 0..iterations {
let mut props = quickleaf::ListProps::default();
props.limit = 1000; // Get 1000 items each time
std::hint::black_box(cache.list(props).unwrap());
}
let duration = start.elapsed();
println!("List operations ({} iterations, 1000 items each): {:?}", iterations, duration);
println!("Average per list operation: {:?}", duration / iterations);
}
fn test_cleanup_operations() {
println!("\n--- Cleanup Operations Test ---");
let mut cache = Cache::new(20000);
// Pre-populate with mix of expired and valid items
for i in 0..10000 {
// Add expired items (very short TTL)
cache.insert_with_ttl(
format!("expired{:05}", i),
format!("value{}", i),
std::time::Duration::from_nanos(1)
);
}
// Add some valid items
for i in 10000..20000 {
cache.insert(format!("valid{:05}", i), format!("value{}", i));
}
// Wait a bit to ensure expiration
std::thread::sleep(std::time::Duration::from_millis(1));
let iterations = 1000;
let start = Instant::now();
for _ in 0..iterations {
std::hint::black_box(cache.cleanup_expired());
}
let duration = start.elapsed();
println!("Cleanup operations ({} iterations): {:?}", iterations, duration);
println!("Average per cleanup: {:?}", duration / iterations);
}