From 947534eb54a635179bb5aea8dfd6654819be9726 Mon Sep 17 00:00:00 2001 From: Liam Gray Date: Thu, 12 Dec 2024 23:22:23 +0000 Subject: [PATCH 1/5] perf: optimise CounterVec hashing, enable other hashers Signed-off-by: Liam Gray --- Cargo.toml | 1 + benches/counter.rs | 26 +++++++++++++++++++++++--- src/vec.rs | 23 ++++++++++++----------- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a62b6296..d34b87e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ push = ["reqwest", "libc", "protobuf"] [dependencies] cfg-if = "^1.0" fnv = "^1.0" +nohash-hasher = "0.2.0" lazy_static = "^1.4" libc = { version = "^0.2", optional = true } parking_lot = "^0.12" diff --git a/benches/counter.rs b/benches/counter.rs index 2ad42c3a..9ebc6d8f 100644 --- a/benches/counter.rs +++ b/benches/counter.rs @@ -11,8 +11,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{black_box, criterion_group, criterion_main, Criterion}; use prometheus::{Counter, CounterVec, IntCounter, Opts}; +use fnv::FnvBuildHasher; use std::collections::HashMap; use std::sync::{atomic, Arc}; use std::thread; @@ -24,7 +25,7 @@ fn bench_counter_with_label_values(c: &mut Criterion) { ) .unwrap(); c.bench_function("counter_with_label_values", |b| { - b.iter(|| counter.with_label_values(&["eins", "zwei", "drei"]).inc()) + b.iter(|| counter.with_label_values(&black_box(["eins", "zwei", "drei"])).inc()) }); } @@ -41,7 +42,25 @@ fn bench_counter_with_mapped_labels(c: &mut Criterion) { labels.insert("two", "zwei"); labels.insert("one", "eins"); labels.insert("three", "drei"); - counter.with(&labels).inc(); + counter.with(&black_box(labels)).inc(); + }) + }); +} + +fn bench_counter_with_mapped_labels_fnv(c: &mut Criterion) { + let counter = CounterVec::new( + Opts::new("benchmark_counter", "A counter to benchmark it."), + &["one", "two", "three"], + ) + .unwrap(); + + c.bench_function("counter_with_mapped_labels_fnv", |b| { + b.iter(|| { + let mut labels = HashMap::with_capacity_and_hasher(3, FnvBuildHasher::default()); + labels.insert("two", "zwei"); + labels.insert("one", "eins"); + labels.insert("three", "drei"); + counter.with(&black_box(labels)).inc(); }) }); } @@ -192,6 +211,7 @@ criterion_group!( bench_counter_with_label_values, bench_counter_with_label_values_concurrent_write, bench_counter_with_mapped_labels, + bench_counter_with_mapped_labels_fnv, bench_counter_with_prepared_mapped_labels, bench_int_counter_no_labels, bench_int_counter_no_labels_concurrent_write, diff --git a/src/vec.rs b/src/vec.rs index 90508e93..c267ff6b 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -2,10 +2,10 @@ // Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0. use std::collections::HashMap; -use std::hash::Hasher; +use std::hash::{BuildHasher, Hasher}; use std::sync::Arc; - use fnv::FnvHasher; +use nohash_hasher::BuildNoHashHasher; use parking_lot::RwLock; use crate::desc::{Desc, Describer}; @@ -26,7 +26,8 @@ pub trait MetricVecBuilder: Send + Sync + Clone { #[derive(Debug)] pub(crate) struct MetricVecCore { - pub children: RwLock>, + // the key is pre-hashed, and so we use a no-hash hasher to avoid hashing again. + pub children: RwLock>>, pub desc: Desc, pub metric_type: MetricType, pub new_metric: T, @@ -59,7 +60,7 @@ impl MetricVecCore { self.get_or_create_metric(h, vals) } - pub fn get_metric_with(&self, labels: &HashMap<&str, &str>) -> Result { + pub fn get_metric_with(&self, labels: &HashMap<&str, &str, S>) -> Result { let h = self.hash_labels(labels)?; if let Some(metric) = self.children.read().get(&h).cloned() { @@ -81,7 +82,7 @@ impl MetricVecCore { Ok(()) } - pub fn delete(&self, labels: &HashMap<&str, &str>) -> Result<()> { + pub fn delete(&self, labels: &HashMap<&str, &str, S>) -> Result<()> { let h = self.hash_labels(labels)?; let mut children = self.children.write(); @@ -113,7 +114,7 @@ impl MetricVecCore { Ok(h.finish()) } - fn hash_labels(&self, labels: &HashMap<&str, &str>) -> Result { + fn hash_labels(&self, labels: &HashMap<&str, &str, S>) -> Result { if labels.len() != self.desc.variable_labels.len() { return Err(Error::InconsistentCardinality { expect: self.desc.variable_labels.len(), @@ -137,7 +138,7 @@ impl MetricVecCore { Ok(h.finish()) } - fn get_label_values<'a>(&self, labels: &'a HashMap<&str, &str>) -> Result> { + fn get_label_values<'a, S: BuildHasher>(&self, labels: &'a HashMap<&str, &str, S>) -> Result> { let mut values = Vec::new(); for name in &self.desc.variable_labels { match labels.get(&name.as_ref()) { @@ -188,7 +189,7 @@ impl MetricVec { pub fn create(metric_type: MetricType, new_metric: T, opts: T::P) -> Result> { let desc = opts.describe()?; let v = MetricVecCore { - children: RwLock::new(HashMap::new()), + children: RwLock::new(HashMap::default()), desc, metric_type, new_metric, @@ -237,7 +238,7 @@ impl MetricVec { /// This method is used for the same purpose as /// `get_metric_with_label_values`. See there for pros and cons of the two /// methods. - pub fn get_metric_with(&self, labels: &HashMap<&str, &str>) -> Result { + pub fn get_metric_with(&self, labels: &HashMap<&str, &str, S>) -> Result { self.v.get_metric_with(labels) } @@ -261,7 +262,7 @@ impl MetricVec { /// `with` works as `get_metric_with`, but panics if an error occurs. The method allows /// neat syntax like: /// httpReqs.with(Labels{"status":"404", "method":"POST"}).inc() - pub fn with(&self, labels: &HashMap<&str, &str>) -> T::M { + pub fn with(&self, labels: &HashMap<&str, &str, S>) -> T::M { self.get_metric_with(labels).unwrap() } @@ -289,7 +290,7 @@ impl MetricVec { /// /// This method is used for the same purpose as `delete_label_values`. See /// there for pros and cons of the two methods. - pub fn remove(&self, labels: &HashMap<&str, &str>) -> Result<()> { + pub fn remove(&self, labels: &HashMap<&str, &str, S>) -> Result<()> { self.v.delete(labels) } From 95ad518b6ce14b88186e9510e148fb2c6e7b391b Mon Sep 17 00:00:00 2001 From: Liam Gray Date: Thu, 20 Mar 2025 13:46:44 +0000 Subject: [PATCH 2/5] Remove nohash-hasher dependency Signed-off-by: Liam Gray --- Cargo.toml | 1 - src/lib.rs | 1 + src/nohash.rs | 23 +++++++++++++++++++++++ src/vec.rs | 4 ++-- 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/nohash.rs diff --git a/Cargo.toml b/Cargo.toml index d34b87e7..a62b6296 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ push = ["reqwest", "libc", "protobuf"] [dependencies] cfg-if = "^1.0" fnv = "^1.0" -nohash-hasher = "0.2.0" lazy_static = "^1.4" libc = { version = "^0.2", optional = true } parking_lot = "^0.12" diff --git a/src/lib.rs b/src/lib.rs index 55cbea35..974dbb48 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -158,6 +158,7 @@ mod errors; mod gauge; mod histogram; mod metrics; +mod nohash; mod pulling_gauge; #[cfg(feature = "push")] mod push; diff --git a/src/nohash.rs b/src/nohash.rs new file mode 100644 index 00000000..98919048 --- /dev/null +++ b/src/nohash.rs @@ -0,0 +1,23 @@ +use std::hash::{BuildHasherDefault, Hasher}; + +/// Inspired by nohash-hasher, but we avoid the crate dependency because it's in public archive. +#[derive(Copy, Clone, Debug, Default)] +pub struct NoHashHasher(u64); + +pub type BuildNoHashHasher = BuildHasherDefault; + +impl Hasher for NoHashHasher { + #[inline] + fn finish(&self) -> u64 { + self.0 + } + + fn write(&mut self, _bytes: &[u8]) { + panic!("Invalid use of NoHashHasher"); + } + + #[inline] + fn write_u64(&mut self, i: u64) { + self.0 = i; + } +} diff --git a/src/vec.rs b/src/vec.rs index c267ff6b..a5a05ce5 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -5,12 +5,12 @@ use std::collections::HashMap; use std::hash::{BuildHasher, Hasher}; use std::sync::Arc; use fnv::FnvHasher; -use nohash_hasher::BuildNoHashHasher; use parking_lot::RwLock; use crate::desc::{Desc, Describer}; use crate::errors::{Error, Result}; use crate::metrics::{Collector, Metric}; +use crate::nohash::BuildNoHashHasher; use crate::proto::{MetricFamily, MetricType}; /// An interface for building a metric vector. @@ -27,7 +27,7 @@ pub trait MetricVecBuilder: Send + Sync + Clone { #[derive(Debug)] pub(crate) struct MetricVecCore { // the key is pre-hashed, and so we use a no-hash hasher to avoid hashing again. - pub children: RwLock>>, + pub children: RwLock>, pub desc: Desc, pub metric_type: MetricType, pub new_metric: T, From 2289dce77b69911ac834e8daf9afa99aa9500d6f Mon Sep 17 00:00:00 2001 From: Liam Gray Date: Thu, 20 Mar 2025 19:15:56 +0000 Subject: [PATCH 3/5] Restrict nohash visibility explicitly Signed-off-by: Liam Gray --- benches/counter.rs | 10 +++++++--- src/nohash.rs | 4 ++-- src/vec.rs | 5 ++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/benches/counter.rs b/benches/counter.rs index 9ebc6d8f..3f51d9d3 100644 --- a/benches/counter.rs +++ b/benches/counter.rs @@ -12,8 +12,8 @@ // limitations under the License. use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use prometheus::{Counter, CounterVec, IntCounter, Opts}; use fnv::FnvBuildHasher; +use prometheus::{Counter, CounterVec, IntCounter, Opts}; use std::collections::HashMap; use std::sync::{atomic, Arc}; use std::thread; @@ -25,7 +25,11 @@ fn bench_counter_with_label_values(c: &mut Criterion) { ) .unwrap(); c.bench_function("counter_with_label_values", |b| { - b.iter(|| counter.with_label_values(&black_box(["eins", "zwei", "drei"])).inc()) + b.iter(|| { + counter + .with_label_values(&black_box(["eins", "zwei", "drei"])) + .inc() + }) }); } @@ -52,7 +56,7 @@ fn bench_counter_with_mapped_labels_fnv(c: &mut Criterion) { Opts::new("benchmark_counter", "A counter to benchmark it."), &["one", "two", "three"], ) - .unwrap(); + .unwrap(); c.bench_function("counter_with_mapped_labels_fnv", |b| { b.iter(|| { diff --git a/src/nohash.rs b/src/nohash.rs index 98919048..da1856ed 100644 --- a/src/nohash.rs +++ b/src/nohash.rs @@ -2,9 +2,9 @@ use std::hash::{BuildHasherDefault, Hasher}; /// Inspired by nohash-hasher, but we avoid the crate dependency because it's in public archive. #[derive(Copy, Clone, Debug, Default)] -pub struct NoHashHasher(u64); +pub(crate) struct NoHashHasher(u64); -pub type BuildNoHashHasher = BuildHasherDefault; +pub(crate) type BuildNoHashHasher = BuildHasherDefault; impl Hasher for NoHashHasher { #[inline] diff --git a/src/vec.rs b/src/vec.rs index a828e5c3..ca663d3c 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -157,7 +157,10 @@ impl MetricVecCore { Ok(h.finish()) } - fn get_label_values<'a, V, S: BuildHasher>(&'a self, labels: &'a HashMap<&str, V, S>) -> Result> + fn get_label_values<'a, V, S: BuildHasher>( + &'a self, + labels: &'a HashMap<&str, V, S>, + ) -> Result> where V: AsRef + std::fmt::Debug, { From 8db16bc18db5011f43e1ef0c53a85916876fae23 Mon Sep 17 00:00:00 2001 From: Liam Gray Date: Thu, 20 Mar 2025 21:44:16 +0000 Subject: [PATCH 4/5] Benchmarks and experiments using rapidhash instead of FNV Signed-off-by: Liam Gray --- Cargo.toml | 1 + benches/counter.rs | 134 +++++++++++++++++++++++++++++++++++++++++++++ src/vec.rs | 4 +- 3 files changed, 138 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a1a2ce6e..988f5406 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ protobuf = { version = "^3.7.2", optional = true } memchr = "^2.3" reqwest = { version = "^0.12", features = ["blocking"], optional = true } thiserror = "^2.0" +rapidhash = { version = "1.4.0" } # path = "../rapidhash" [target.'cfg(target_os = "linux")'.dependencies] procfs = { version = "^0.17", optional = true, default-features = false } diff --git a/benches/counter.rs b/benches/counter.rs index 3f51d9d3..7e818b6c 100644 --- a/benches/counter.rs +++ b/benches/counter.rs @@ -17,6 +17,7 @@ use prometheus::{Counter, CounterVec, IntCounter, Opts}; use std::collections::HashMap; use std::sync::{atomic, Arc}; use std::thread; +use rapidhash::RapidBuildHasher; fn bench_counter_with_label_values(c: &mut Criterion) { let counter = CounterVec::new( @@ -69,6 +70,132 @@ fn bench_counter_with_mapped_labels_fnv(c: &mut Criterion) { }); } +fn bench_counter_with_mapped_labels_rapidhash(c: &mut Criterion) { + let counter = CounterVec::new( + Opts::new("benchmark_counter", "A counter to benchmark it."), + &["one", "two", "three"], + ) + .unwrap(); + + c.bench_function("counter_with_mapped_labels_rapidhash", |b| { + b.iter(|| { + let mut labels = HashMap::with_capacity_and_hasher(3, RapidBuildHasher::default()); + labels.insert("two", "zwei"); + labels.insert("one", "eins"); + labels.insert("three", "drei"); + counter.with(&black_box(labels)).inc(); + }) + }); +} + +fn bench_counter_with_mapped_mid_labels(c: &mut Criterion) { + let counter = CounterVec::new( + Opts::new("benchmark_counter", "A counter to benchmark it."), + &["midsize_one", "midsize_two", "midsize_three"], + ) + .unwrap(); + + c.bench_function("counter_with_mapped_mid_labels", |b| { + b.iter(|| { + let mut labels = HashMap::with_capacity(3); + labels.insert("midsize_two", "midsize_zwei"); + labels.insert("midsize_one", "midsize_eins"); + labels.insert("midsize_three", "midsize_drei"); + counter.with(&black_box(labels)).inc(); + }) + }); +} + +fn bench_counter_with_mapped_mid_labels_fnv(c: &mut Criterion) { + let counter = CounterVec::new( + Opts::new("benchmark_counter", "A counter to benchmark it."), + &["midsize_one", "midsize_two", "midsize_three"], + ) + .unwrap(); + + c.bench_function("counter_with_mapped_mid_labels_fnv", |b| { + b.iter(|| { + let mut labels = HashMap::with_capacity_and_hasher(3, FnvBuildHasher::default()); + labels.insert("midsize_two", "midsize_zwei"); + labels.insert("midsize_one", "midsize_eins"); + labels.insert("midsize_three", "midsize_drei"); + counter.with(&black_box(labels)).inc(); + }) + }); +} + +fn bench_counter_with_mapped_mid_labels_rapidhash(c: &mut Criterion) { + let counter = CounterVec::new( + Opts::new("benchmark_counter", "A counter to benchmark it."), + &["midsize_one", "midsize_two", "midsize_three"], + ) + .unwrap(); + + c.bench_function("counter_with_mapped_mid_labels_rapidhash", |b| { + b.iter(|| { + let mut labels = HashMap::with_capacity_and_hasher(3, RapidBuildHasher::default()); + labels.insert("midsize_two", "midsize_zwei"); + labels.insert("midsize_one", "midsize_eins"); + labels.insert("midsize_three", "midsize_drei"); + counter.with(&black_box(labels)).inc(); + }) + }); +} + +fn bench_counter_with_mapped_long_labels(c: &mut Criterion) { + let counter = CounterVec::new( + Opts::new("benchmark_counter", "A counter to benchmark it."), + &["longer_field_number_one", "longer_field_number_two", "longer_field_number_three"], + ) + .unwrap(); + + c.bench_function("counter_with_mapped_longer_labels", |b| { + b.iter(|| { + let mut labels = HashMap::with_capacity(3); + labels.insert("longer_field_number_two", "longer_field_number_zwei"); + labels.insert("longer_field_number_one", "longer_field_number_eins"); + labels.insert("longer_field_number_three", "longer_field_number_drei"); + counter.with(&black_box(labels)).inc(); + }) + }); +} + +fn bench_counter_with_mapped_long_labels_fnv(c: &mut Criterion) { + let counter = CounterVec::new( + Opts::new("benchmark_counter", "A counter to benchmark it."), + &["longer_field_number_one", "longer_field_number_two", "longer_field_number_three"], + ) + .unwrap(); + + c.bench_function("counter_with_mapped_longer_labels_fnv", |b| { + b.iter(|| { + let mut labels = HashMap::with_capacity_and_hasher(3, FnvBuildHasher::default()); + labels.insert("longer_field_number_two", "longer_field_number_zwei"); + labels.insert("longer_field_number_one", "longer_field_number_eins"); + labels.insert("longer_field_number_three", "longer_field_number_drei"); + counter.with(&black_box(labels)).inc(); + }) + }); +} + +fn bench_counter_with_mapped_long_labels_rapidhash(c: &mut Criterion) { + let counter = CounterVec::new( + Opts::new("benchmark_counter", "A counter to benchmark it."), + &["longer_field_number_one", "longer_field_number_two", "longer_field_number_three"], + ) + .unwrap(); + + c.bench_function("counter_with_mapped_longer_labels_rapidhash", |b| { + b.iter(|| { + let mut labels = HashMap::with_capacity_and_hasher(3, RapidBuildHasher::default()); + labels.insert("longer_field_number_two", "longer_field_number_zwei"); + labels.insert("longer_field_number_one", "longer_field_number_eins"); + labels.insert("longer_field_number_three", "longer_field_number_drei"); + counter.with(&black_box(labels)).inc(); + }) + }); +} + fn bench_counter_with_prepared_mapped_labels(c: &mut Criterion) { let counter = CounterVec::new( Opts::new("benchmark_counter", "A counter to benchmark it."), @@ -216,6 +343,13 @@ criterion_group!( bench_counter_with_label_values_concurrent_write, bench_counter_with_mapped_labels, bench_counter_with_mapped_labels_fnv, + bench_counter_with_mapped_labels_rapidhash, + bench_counter_with_mapped_mid_labels, + bench_counter_with_mapped_mid_labels_fnv, + bench_counter_with_mapped_mid_labels_rapidhash, + bench_counter_with_mapped_long_labels, + bench_counter_with_mapped_long_labels_fnv, + bench_counter_with_mapped_long_labels_rapidhash, bench_counter_with_prepared_mapped_labels, bench_int_counter_no_labels, bench_int_counter_no_labels_concurrent_write, diff --git a/src/vec.rs b/src/vec.rs index ca663d3c..c43a266a 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -5,7 +5,9 @@ use std::collections::HashMap; use std::hash::{BuildHasher, Hasher}; use std::sync::Arc; -use fnv::FnvHasher; +// TODO: experimenting, alternating while benchmarking +// use fnv::FnvHasher; +use rapidhash::RapidHasher as FnvHasher; use parking_lot::RwLock; use crate::desc::{Desc, Describer}; From e7668e3ba73935065c0ec165864bcc449979b8f6 Mon Sep 17 00:00:00 2001 From: Liam Gray Date: Fri, 21 Mar 2025 13:47:47 +0000 Subject: [PATCH 5/5] Fix cargo fmt Signed-off-by: Liam Gray --- Cargo.toml | 2 +- benches/counter.rs | 34 +++++++++++++++++++++++----------- src/vec.rs | 1 + 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 988f5406..76936b56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ protobuf = { version = "^3.7.2", optional = true } memchr = "^2.3" reqwest = { version = "^0.12", features = ["blocking"], optional = true } thiserror = "^2.0" -rapidhash = { version = "1.4.0" } # path = "../rapidhash" +rapidhash = "1.4.0" [target.'cfg(target_os = "linux")'.dependencies] procfs = { version = "^0.17", optional = true, default-features = false } diff --git a/benches/counter.rs b/benches/counter.rs index 7e818b6c..49d8fff0 100644 --- a/benches/counter.rs +++ b/benches/counter.rs @@ -14,10 +14,10 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use fnv::FnvBuildHasher; use prometheus::{Counter, CounterVec, IntCounter, Opts}; +use rapidhash::RapidBuildHasher; use std::collections::HashMap; use std::sync::{atomic, Arc}; use std::thread; -use rapidhash::RapidBuildHasher; fn bench_counter_with_label_values(c: &mut Criterion) { let counter = CounterVec::new( @@ -75,7 +75,7 @@ fn bench_counter_with_mapped_labels_rapidhash(c: &mut Criterion) { Opts::new("benchmark_counter", "A counter to benchmark it."), &["one", "two", "three"], ) - .unwrap(); + .unwrap(); c.bench_function("counter_with_mapped_labels_rapidhash", |b| { b.iter(|| { @@ -93,7 +93,7 @@ fn bench_counter_with_mapped_mid_labels(c: &mut Criterion) { Opts::new("benchmark_counter", "A counter to benchmark it."), &["midsize_one", "midsize_two", "midsize_three"], ) - .unwrap(); + .unwrap(); c.bench_function("counter_with_mapped_mid_labels", |b| { b.iter(|| { @@ -111,7 +111,7 @@ fn bench_counter_with_mapped_mid_labels_fnv(c: &mut Criterion) { Opts::new("benchmark_counter", "A counter to benchmark it."), &["midsize_one", "midsize_two", "midsize_three"], ) - .unwrap(); + .unwrap(); c.bench_function("counter_with_mapped_mid_labels_fnv", |b| { b.iter(|| { @@ -129,7 +129,7 @@ fn bench_counter_with_mapped_mid_labels_rapidhash(c: &mut Criterion) { Opts::new("benchmark_counter", "A counter to benchmark it."), &["midsize_one", "midsize_two", "midsize_three"], ) - .unwrap(); + .unwrap(); c.bench_function("counter_with_mapped_mid_labels_rapidhash", |b| { b.iter(|| { @@ -145,9 +145,13 @@ fn bench_counter_with_mapped_mid_labels_rapidhash(c: &mut Criterion) { fn bench_counter_with_mapped_long_labels(c: &mut Criterion) { let counter = CounterVec::new( Opts::new("benchmark_counter", "A counter to benchmark it."), - &["longer_field_number_one", "longer_field_number_two", "longer_field_number_three"], + &[ + "longer_field_number_one", + "longer_field_number_two", + "longer_field_number_three", + ], ) - .unwrap(); + .unwrap(); c.bench_function("counter_with_mapped_longer_labels", |b| { b.iter(|| { @@ -163,9 +167,13 @@ fn bench_counter_with_mapped_long_labels(c: &mut Criterion) { fn bench_counter_with_mapped_long_labels_fnv(c: &mut Criterion) { let counter = CounterVec::new( Opts::new("benchmark_counter", "A counter to benchmark it."), - &["longer_field_number_one", "longer_field_number_two", "longer_field_number_three"], + &[ + "longer_field_number_one", + "longer_field_number_two", + "longer_field_number_three", + ], ) - .unwrap(); + .unwrap(); c.bench_function("counter_with_mapped_longer_labels_fnv", |b| { b.iter(|| { @@ -181,9 +189,13 @@ fn bench_counter_with_mapped_long_labels_fnv(c: &mut Criterion) { fn bench_counter_with_mapped_long_labels_rapidhash(c: &mut Criterion) { let counter = CounterVec::new( Opts::new("benchmark_counter", "A counter to benchmark it."), - &["longer_field_number_one", "longer_field_number_two", "longer_field_number_three"], + &[ + "longer_field_number_one", + "longer_field_number_two", + "longer_field_number_three", + ], ) - .unwrap(); + .unwrap(); c.bench_function("counter_with_mapped_longer_labels_rapidhash", |b| { b.iter(|| { diff --git a/src/vec.rs b/src/vec.rs index c43a266a..43a84df4 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -8,6 +8,7 @@ use std::sync::Arc; // TODO: experimenting, alternating while benchmarking // use fnv::FnvHasher; use rapidhash::RapidHasher as FnvHasher; + use parking_lot::RwLock; use crate::desc::{Desc, Describer};