14
14
15
15
use std:: sync:: Arc ;
16
16
17
+ use csv:: Reader ;
17
18
use foyer_memory:: { Cache , CacheBuilder , FifoConfig , LfuConfig , LruConfig , S3FifoConfig } ;
18
19
use rand:: { distributions:: Distribution , thread_rng} ;
19
20
@@ -66,7 +67,7 @@ fn cache_hit(cache: Cache<CacheKey, CacheValue>, keys: Arc<Vec<CacheKey>>) -> f6
66
67
cache. insert ( key. clone ( ) , ( ) ) ;
67
68
}
68
69
}
69
- hit as f64 / ITERATIONS as f64
70
+ ( hit as f64 ) / ( keys . len ( ) as f64 )
70
71
}
71
72
72
73
fn moka_cache_hit ( cache : & moka:: sync:: Cache < CacheKey , CacheValue > , keys : & [ String ] ) -> f64 {
@@ -79,7 +80,7 @@ fn moka_cache_hit(cache: &moka::sync::Cache<CacheKey, CacheValue>, keys: &[Strin
79
80
cache. insert ( key. clone ( ) , ( ) ) ;
80
81
}
81
82
}
82
- hit as f64 / ITERATIONS as f64
83
+ hit as f64 / ( keys . len ( ) as f64 )
83
84
}
84
85
85
86
fn new_fifo_cache ( capacity : usize ) -> Cache < CacheKey , CacheValue > {
@@ -130,33 +131,21 @@ fn new_s3fifo_cache_w_ghost(capacity: usize) -> Cache<CacheKey, CacheValue> {
130
131
. with_shards ( SHARDS )
131
132
. with_eviction_config ( S3FifoConfig {
132
133
small_queue_capacity_ratio : 0.1 ,
133
- ghost_queue_capacity_ratio : 10 .0,
134
+ ghost_queue_capacity_ratio : 1 .0,
134
135
small_to_main_freq_threshold : 2 ,
135
136
} )
136
137
. with_object_pool_capacity ( OBJECT_POOL_CAPACITY )
137
138
. build ( )
138
139
}
139
140
140
- fn bench_one ( zif_exp : f64 , cache_size_percent : f64 ) {
141
- print ! ( "{zif_exp:6.2}, {cache_size_percent:6}{:6}" , "" ) ;
142
- let mut rng = thread_rng ( ) ;
143
- let zipf = zipf:: ZipfDistribution :: new ( ITEMS , zif_exp) . unwrap ( ) ;
144
-
145
- let cache_size = ( ITEMS as f64 * cache_size_percent) as usize ;
146
-
141
+ fn bench_workload ( keys : Vec < String > , cache_size : usize ) {
147
142
let fifo_cache = new_fifo_cache ( cache_size) ;
148
143
let lru_cache = new_lru_cache ( cache_size) ;
149
144
let lfu_cache = new_lfu_cache ( cache_size) ;
150
145
let s3fifo_cache_wo_ghost = new_s3fifo_cache_wo_ghost ( cache_size) ;
151
146
let s3fifo_cache_w_ghost = new_s3fifo_cache_w_ghost ( cache_size) ;
152
147
let moka_cache = moka:: sync:: Cache :: new ( cache_size as u64 ) ;
153
148
154
- let mut keys = Vec :: with_capacity ( ITERATIONS ) ;
155
- for _ in 0 ..ITERATIONS {
156
- let key = zipf. sample ( & mut rng) . to_string ( ) ;
157
- keys. push ( key. clone ( ) ) ;
158
- }
159
-
160
149
let keys = Arc :: new ( keys) ;
161
150
162
151
// Use multiple threads to simulate concurrent read-through requests.
@@ -212,10 +201,24 @@ fn bench_one(zif_exp: f64, cache_size_percent: f64) {
212
201
println ! ( ) ;
213
202
}
214
203
204
+ fn bench_one ( zif_exp : f64 , cache_size_percent : f64 ) {
205
+ print ! ( "{zif_exp:6.2}, {cache_size_percent:6}{:6}" , "" ) ;
206
+ let mut rng = thread_rng ( ) ;
207
+ let zipf = zipf:: ZipfDistribution :: new ( ITEMS , zif_exp) . unwrap ( ) ;
208
+
209
+ let cache_size = ( ITEMS as f64 * cache_size_percent) as usize ;
210
+ let mut keys = Vec :: with_capacity ( ITERATIONS ) ;
211
+ for _ in 0 ..ITERATIONS {
212
+ let key = zipf. sample ( & mut rng) . to_string ( ) ;
213
+ keys. push ( key. clone ( ) ) ;
214
+ }
215
+ bench_workload ( keys, cache_size) ;
216
+ }
217
+
215
218
fn bench_zipf_hit ( ) {
216
219
println ! (
217
220
"{:30}{:16}{:16}{:16}{:16}{:16}{:16}" ,
218
- "zif_exp, cache_size" , "fifo" , "lru" , "lfu" , "s3fifo (0g)" , "s3fifo (10g )" , "moka"
221
+ "zif_exp, cache_size" , "fifo" , "lru" , "lfu" , "s3fifo (0g)" , "s3fifo (1g )" , "moka"
219
222
) ;
220
223
for zif_exp in [ 0.9 , 1.0 , 1.05 , 1.1 , 1.5 ] {
221
224
for cache_capacity in [ 0.005 , 0.01 , 0.05 , 0.1 , 0.25 ] {
@@ -224,6 +227,67 @@ fn bench_zipf_hit() {
224
227
}
225
228
}
226
229
230
+ fn read_twitter_trace ( path : & str , limit : usize ) -> Vec < String > {
231
+ let file = std:: fs:: File :: open ( path) . unwrap ( ) ;
232
+ let mut reader = Reader :: from_reader ( file) ;
233
+ let mut keys = Vec :: new ( ) ;
234
+ for result in reader. records ( ) {
235
+ let record = result. unwrap ( ) ;
236
+ let key = record. get ( 1 ) . unwrap ( ) . to_string ( ) ;
237
+ keys. push ( key) ;
238
+ if keys. len ( ) >= limit {
239
+ break ;
240
+ }
241
+ }
242
+ keys
243
+ }
244
+
245
+ /*
246
+ cache_size fifo lru lfu s3fifo (0g) s3fifo (1g) moka
247
+ 50000 67.50% 70.51% 74.99% 70.88% 72.33% 64.70%
248
+ zif_exp, cache_size fifo lru lfu s3fifo (0g) s3fifo (1g) moka
249
+ 0.90, 0.005 16.24% 19.20% 32.38% 32.06% 31.94% 33.44%
250
+ 0.90, 0.01 22.55% 26.21% 38.56% 39.27% 38.46% 37.86%
251
+ 0.90, 0.05 41.10% 45.61% 55.41% 56.64% 55.37% 55.19%
252
+ 0.90, 0.1 51.05% 55.69% 63.81% 65.27% 63.61% 64.16%
253
+ 0.90, 0.25 66.76% 71.15% 76.17% 77.53% 75.68% 77.11%
254
+ 1.00, 0.005 26.59% 31.05% 44.11% 44.37% 43.54% 45.54%
255
+ 1.00, 0.01 34.36% 39.13% 50.64% 51.40% 50.59% 50.69%
256
+ 1.00, 0.05 54.03% 58.75% 66.80% 67.94% 66.81% 66.91%
257
+ 1.00, 0.1 63.16% 67.62% 73.93% 75.01% 73.83% 74.38%
258
+ 1.00, 0.25 76.17% 79.93% 83.61% 84.53% 83.27% 84.36%
259
+ 1.05, 0.005 32.64% 37.67% 50.23% 50.31% 49.63% 51.83%
260
+ 1.05, 0.01 40.90% 46.02% 56.71% 57.59% 56.67% 56.99%
261
+ 1.05, 0.05 60.44% 65.03% 72.05% 73.02% 72.09% 72.31%
262
+ 1.05, 0.1 68.90% 73.10% 78.50% 79.36% 78.39% 78.98%
263
+ 1.05, 0.25 80.34% 83.71% 86.77% 87.47% 86.49% 87.40%
264
+ 1.10, 0.005 38.98% 44.45% 56.25% 56.62% 55.62% 57.89%
265
+ 1.10, 0.01 47.66% 52.98% 62.65% 63.55% 62.62% 63.22%
266
+ 1.10, 0.05 66.55% 70.91% 76.90% 77.77% 76.96% 77.22%
267
+ 1.10, 0.1 74.27% 78.07% 82.56% 83.38% 82.51% 82.97%
268
+ 1.10, 0.25 84.19% 87.10% 89.56% 90.08% 89.34% 90.08%
269
+ 1.50, 0.005 81.20% 85.30% 88.90% 89.32% 88.79% 89.92%
270
+ 1.50, 0.01 86.91% 89.87% 92.25% 92.66% 92.29% 92.76%
271
+ 1.50, 0.05 94.77% 96.05% 96.96% 97.08% 96.96% 97.10%
272
+ 1.50, 0.1 96.64% 97.50% 98.05% 98.10% 98.04% 98.12%
273
+ 1.50, 0.25 98.37% 98.82% 99.05% 99.03% 99.03% 99.10%
274
+ */
227
275
fn main ( ) {
276
+ // Try to read the csv file path by environment variable.
277
+ let path = std:: env:: var ( "TWITTER_TRACE_PATH" ) . ok ( ) ;
278
+ if let Some ( path) = path {
279
+ // Limit the number of keys to read.
280
+ // MAX means read all keys, which may take a really long time.
281
+ let limit = usize:: MAX ;
282
+ let capacity = 50_000 ;
283
+ let keys = read_twitter_trace ( & path, limit) ;
284
+ println ! (
285
+ "{:30}{:16}{:16}{:16}{:16}{:16}{:16}" ,
286
+ "cache_size" , "fifo" , "lru" , "lfu" , "s3fifo (0g)" , "s3fifo (1g)" , "moka"
287
+ ) ;
288
+ print ! ( "{capacity:10}" ) ;
289
+ print ! ( "{:9}" , " " ) ;
290
+ bench_workload ( keys, capacity) ;
291
+ }
228
292
bench_zipf_hit ( ) ;
229
293
}
0 commit comments