Use write! to fix clippy and save heap allocation (#25220)

This commit is contained in:
sakridge 2022-05-16 15:39:33 -05:00 committed by GitHub
parent 21e066ef26
commit a63d99fd11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 19 deletions

View File

@ -8,12 +8,32 @@ use {
solana_metrics::{
counter::CounterPoint,
datapoint::DataPoint,
metrics::{test_mocks::MockMetricsWriter, MetricsAgent},
metrics::{serialize_points, test_mocks::MockMetricsWriter, MetricsAgent},
},
std::{sync::Arc, time::Duration},
test::Bencher,
};
#[bench]
fn bench_write_points(bencher: &mut Bencher) {
let points = (0..10)
.into_iter()
.map(|_| {
DataPoint::new("measurement")
.add_field_i64("i", 0)
.add_field_i64("abc123", 2)
.add_field_i64("this-is-my-very-long-field-name", 3)
.clone()
})
.collect();
let host_id = "benchmark-host-id";
bencher.iter(|| {
for _ in 0..10 {
test::black_box(serialize_points(&points, host_id));
}
})
}
#[bench]
fn bench_datapoint_submission(bencher: &mut Bencher) {
let writer = Arc::new(MockMetricsWriter::new());

View File

@ -12,6 +12,7 @@ use {
collections::HashMap,
convert::Into,
env,
fmt::Write,
sync::{Arc, Barrier, Mutex, Once, RwLock},
thread,
time::{Duration, Instant, UNIX_EPOCH},
@ -77,6 +78,35 @@ impl InfluxDbMetricsWriter {
}
}
pub fn serialize_points(points: &Vec<DataPoint>, host_id: &str) -> String {
const TIMESTAMP_LEN: usize = 20;
const HOST_ID_LEN: usize = 8; // "host_id=".len()
const EXTRA_LEN: usize = 2; // "=,".len()
let mut len = 0;
for point in points {
for (name, value) in &point.fields {
len += name.len() + value.len() + EXTRA_LEN;
}
len += point.name.len();
len += TIMESTAMP_LEN;
len += host_id.len() + HOST_ID_LEN;
}
let mut line = String::with_capacity(len);
for point in points {
let _ = write!(line, "{},host_id={}", &point.name, host_id);
let mut first = true;
for (name, value) in point.fields.iter() {
let _ = write!(line, "{}{}={}", if first { ' ' } else { ',' }, name, value);
first = false;
}
let timestamp = point.timestamp.duration_since(UNIX_EPOCH);
let nanos = timestamp.unwrap().as_nanos();
let _ = writeln!(line, " {}", nanos);
}
line
}
impl MetricsWriter for InfluxDbMetricsWriter {
fn write(&self, points: Vec<DataPoint>) {
if let Some(ref write_url) = self.write_url {
@ -84,24 +114,7 @@ impl MetricsWriter for InfluxDbMetricsWriter {
let host_id = HOST_ID.read().unwrap();
let mut line = String::new();
for point in points {
line.push_str(&format!("{},host_id={}", &point.name, &host_id));
let mut first = true;
for (name, value) in point.fields {
line.push_str(&format!(
"{}{}={}",
if first { ' ' } else { ',' },
name,
value
));
first = false;
}
let timestamp = point.timestamp.duration_since(UNIX_EPOCH);
let nanos = timestamp.unwrap().as_nanos();
line.push_str(&format!(" {}\n", nanos));
}
let line = serialize_points(&points, &host_id);
let client = reqwest::blocking::Client::builder()
.timeout(Duration::from_secs(5))