bench-cli: Support JSON output (#10771)

* Add dependencies

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Make benchmark results serializable

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Add `--json[-file]` options

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Enable JSON output

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Use specific serde version

Polkadot does not compile otherwise.

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Review comments

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Review comment: fs::write

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
Oliver Tale-Yazdi
2022-02-02 15:25:13 +01:00
committed by GitHub
parent 46f4396657
commit 99fae0cd57
6 changed files with 84 additions and 46 deletions
+25
View File
@@ -22,12 +22,15 @@ use frame_support::{
pallet_prelude::*,
traits::StorageInfo,
};
#[cfg(feature = "std")]
use serde::Serialize;
use sp_io::hashing::blake2_256;
use sp_runtime::traits::TrailingZeroInput;
use sp_std::{prelude::Box, vec::Vec};
use sp_storage::TrackedStorageKey;
/// An alphabet of possible parameters to use for benchmarking.
#[cfg_attr(feature = "std", derive(Serialize))]
#[derive(Encode, Decode, Clone, Copy, PartialEq, Debug)]
#[allow(missing_docs)]
#[allow(non_camel_case_types)]
@@ -68,13 +71,17 @@ impl std::fmt::Display for BenchmarkParameter {
}
/// The results of a single of benchmark.
#[cfg_attr(feature = "std", derive(Serialize))]
#[derive(Encode, Decode, Clone, PartialEq, Debug)]
pub struct BenchmarkBatch {
/// The pallet containing this benchmark.
#[cfg_attr(feature = "std", serde(with = "serde_as_str"))]
pub pallet: Vec<u8>,
/// The instance of this pallet being benchmarked.
#[cfg_attr(feature = "std", serde(with = "serde_as_str"))]
pub instance: Vec<u8>,
/// The extrinsic (or benchmark name) of this benchmark.
#[cfg_attr(feature = "std", serde(with = "serde_as_str"))]
pub benchmark: Vec<u8>,
/// The results from this benchmark.
pub results: Vec<BenchmarkResult>,
@@ -82,13 +89,17 @@ pub struct BenchmarkBatch {
// TODO: could probably make API cleaner here.
/// The results of a single of benchmark, where time and db results are separated.
#[cfg_attr(feature = "std", derive(Serialize))]
#[derive(Encode, Decode, Clone, PartialEq, Debug)]
pub struct BenchmarkBatchSplitResults {
/// The pallet containing this benchmark.
#[cfg_attr(feature = "std", serde(with = "serde_as_str"))]
pub pallet: Vec<u8>,
/// The instance of this pallet being benchmarked.
#[cfg_attr(feature = "std", serde(with = "serde_as_str"))]
pub instance: Vec<u8>,
/// The extrinsic (or benchmark name) of this benchmark.
#[cfg_attr(feature = "std", serde(with = "serde_as_str"))]
pub benchmark: Vec<u8>,
/// The extrinsic timing results from this benchmark.
pub time_results: Vec<BenchmarkResult>,
@@ -99,6 +110,7 @@ pub struct BenchmarkBatchSplitResults {
/// Result from running benchmarks on a FRAME pallet.
/// Contains duration of the function call in nanoseconds along with the benchmark parameters
/// used for that benchmark result.
#[cfg_attr(feature = "std", derive(Serialize))]
#[derive(Encode, Decode, Default, Clone, PartialEq, Debug)]
pub struct BenchmarkResult {
pub components: Vec<(BenchmarkParameter, u32)>,
@@ -109,6 +121,7 @@ pub struct BenchmarkResult {
pub writes: u32,
pub repeat_writes: u32,
pub proof_size: u32,
#[cfg_attr(feature = "std", serde(skip_serializing))]
pub keys: Vec<(Vec<u8>, u32, u32, bool)>,
}
@@ -118,6 +131,18 @@ impl BenchmarkResult {
}
}
/// Helper module to make serde serialize `Vec<u8>` as strings.
#[cfg(feature = "std")]
mod serde_as_str {
pub fn serialize<S>(value: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let s = std::str::from_utf8(value).map_err(serde::ser::Error::custom)?;
serializer.collect_str(s)
}
}
/// Possible errors returned from the benchmarking pipeline.
#[derive(Clone, PartialEq, Debug)]
pub enum BenchmarkError {