sonic-net / sonic-dash-ha

SONiC SmartSwitch HA related services
Other
3 stars 5 forks source link

Change DashMap to RWLock<HashMap> in swbusd #25

Open yue-fred-gao opened 3 days ago

yue-fred-gao commented 3 days ago

Oliver found DashMap is 20x to 40x slower than RwLock

erer1243 commented 3 days ago

Yes. This is not a surprise (obviously the more complicated version will be slower) but more a question of if we will be writing to the route table so often that it's worth the read penalty. I don't think we will.

here is the code and results:

results ```js maps: inserting into empty HashMap time: [19.328 ns 19.519 ns 19.699 ns] Found 3 outliers among 100 measurements (3.00%) 1 (1.00%) high mild 2 (2.00%) high severe maps: inserting into empty std::RwLock time: [30.183 ns 30.433 ns 30.670 ns] Found 4 outliers among 100 measurements (4.00%) 3 (3.00%) high mild 1 (1.00%) high severe maps: inserting into empty parking_lot::RwLock time: [36.358 ns 36.774 ns 37.197 ns] Found 11 outliers among 100 measurements (11.00%) 6 (6.00%) high mild 5 (5.00%) high severe maps: inserting into empty DashMap time: [1.3275 µs 1.3583 µs 1.3866 µs] maps: reading from HashMap time: [17.660 ns 17.914 ns 18.216 ns] Found 3 outliers among 100 measurements (3.00%) 2 (2.00%) high mild 1 (1.00%) high severe maps: reading from std::RwLock time: [27.428 ns 27.757 ns 28.105 ns] Found 3 outliers among 100 measurements (3.00%) 2 (2.00%) high mild 1 (1.00%) high severe maps: reading from parking_lot::RwLock time: [33.430 ns 33.768 ns 34.145 ns] Found 3 outliers among 100 measurements (3.00%) 2 (2.00%) high mild 1 (1.00%) high severe maps: reading from DashMap time: [433.28 ns 463.76 ns 489.86 ns] ```
code ```rs use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use rand::random; criterion_group!(b, hashmaps); criterion_main!(b); fn hashmaps(c: &mut Criterion) { use dashmap::DashMap; use std::{collections::HashMap, sync::RwLock}; c.bench_function("maps: inserting into empty HashMap", |b| { b.iter_batched( || (HashMap::::with_capacity(1), random::()), |(mut map, n)| map.insert(n, n), BatchSize::SmallInput, ); }); c.bench_function("maps: inserting into empty std::RwLock", |b| { b.iter_batched( || { ( RwLock::new(HashMap::::with_capacity(1)), random::(), ) }, |(map, n)| map.write().unwrap().insert(n, n), BatchSize::SmallInput, ); }); c.bench_function( "maps: inserting into empty parking_lot::RwLock", |b| { b.iter_batched( || { ( parking_lot::RwLock::new(HashMap::::with_capacity(1)), random::(), ) }, |(map, n)| map.write().insert(n, n), BatchSize::SmallInput, ); }, ); c.bench_function("maps: inserting into empty DashMap", |b| { b.iter_batched( || (DashMap::::with_capacity(1), random::()), |(map, n)| map.insert(n, n), BatchSize::SmallInput, ); }); c.bench_function("maps: reading from HashMap", |b| { b.iter_batched( || { let n = random::(); (HashMap::::from_iter([(n, n)]), n) }, |(map, n)| { map.get(&n); }, BatchSize::SmallInput, ); }); c.bench_function("maps: reading from std::RwLock", |b| { b.iter_batched( || { let n = random::(); (RwLock::new(HashMap::::from_iter([(n, n)])), n) }, |(map, n)| { map.read().unwrap().get(&n); }, BatchSize::SmallInput, ); }); c.bench_function("maps: reading from parking_lot::RwLock", |b| { b.iter_batched( || { let n = random::(); ( parking_lot::RwLock::new(HashMap::::from_iter([(n, n)])), n, ) }, |(map, n)| { map.read().get(&n); }, BatchSize::SmallInput, ); }); c.bench_function("maps: reading from DashMap", |b| { b.iter_batched( || { let n = random::(); (DashMap::::from_iter([(n, n)]), n) }, |(map, n)| { map.get(&n); }, BatchSize::SmallInput, ); }); } ```