referrerpolicy=no-referrer-when-downgrade

frame_benchmarking_cli/shared/
record.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Defines the [`BenchRecord`] and its facilities for computing [`super::Stats`].
19
20use sc_cli::Result;
21use sc_service::Configuration;
22
23use log::info;
24use serde::Serialize;
25use std::{fs, path::PathBuf, time::Duration};
26
27use super::Stats;
28
29/// Raw output of a Storage benchmark.
30#[derive(Debug, Default, Clone, Serialize)]
31pub struct BenchRecord {
32	/// Multi-Map of value sizes and the time that it took to access them.
33	ns_per_size: Vec<(u64, u64)>,
34}
35
36impl BenchRecord {
37	/// Appends a new record. Uses safe casts.
38	pub fn append(&mut self, size: usize, d: Duration) -> Result<()> {
39		let size: u64 = size.try_into().map_err(|e| format!("Size overflow u64: {}", e))?;
40		let ns: u64 = d
41			.as_nanos()
42			.try_into()
43			.map_err(|e| format!("Nanoseconds overflow u64: {}", e))?;
44		self.ns_per_size.push((size, ns));
45		Ok(())
46	}
47
48	/// Returns the statistics for *time* and *value size*.
49	pub fn calculate_stats(self) -> Result<(Stats, Stats)> {
50		let (size, time): (Vec<_>, Vec<_>) = self.ns_per_size.into_iter().unzip();
51		let size = Stats::new(&size)?;
52		let time = Stats::new(&time)?;
53		Ok((time, size)) // The swap of time/size here is intentional.
54	}
55
56	/// Unless a path is specified, saves the raw results in a json file in the current directory.
57	/// Prefixes it with the DB name and suffixed with `path_suffix`.
58	pub fn save_json(&self, cfg: &Configuration, out_path: &PathBuf, suffix: &str) -> Result<()> {
59		let mut path = PathBuf::from(out_path);
60		if path.is_dir() || path.as_os_str().is_empty() {
61			path.push(&format!("{}_{}", cfg.database, suffix).to_lowercase());
62			path.set_extension("json");
63		}
64
65		let json = serde_json::to_string_pretty(&self)
66			.map_err(|e| format!("Serializing as JSON: {:?}", e))?;
67
68		fs::write(&path, json)?;
69		info!("Raw data written to {:?}", fs::canonicalize(&path)?);
70		Ok(())
71	}
72}