Compare commits

...

10 Commits

Author SHA1 Message Date
Richard
83267e44e1
Merge 539995aad1 into 4a00f1821c 2024-06-22 22:46:39 +02:00
Bryan Honof
4a00f1821c docs: Add flox install 2024-06-22 22:42:33 +02:00
Richard Montoya
539995aad1 formtating 2023-07-28 19:39:41 -05:00
Richard Montoya
c8bfd59d81 Adds the import-json to the cli options 2023-07-28 19:30:33 -05:00
Richard Montoya
610c8c4a8a Add functionality to load a previous run 2023-07-28 19:26:30 -05:00
Richard Montoya
0033f23006 Make the JSON public for use in import
Modify the JSON export module so it can be used as a reference for
importing and deserializing.
2023-07-28 19:23:38 -05:00
Richard Montoya
b90fa23237 modify types for serialization and deserialization
The existing types need to be modified so they can be used for the
deserialization process.
2023-07-26 23:09:41 -05:00
Richard
6746cf120d
Merge branch 'sharkdp:master' into master 2023-07-25 12:09:28 -05:00
Richard Montoya
1cb474f452 bump the minimum supported rust version. 2023-07-24 15:10:52 -05:00
Richard Montoya
8c145f994d fix: update Cargo.lock to remove proc_macro_span 2023-07-22 00:35:49 -05:00
8 changed files with 76 additions and 14 deletions

View File

@ -240,6 +240,14 @@ On NixOS, hyperfine can be installed [from the official repositories](https://ni
nix-env -i hyperfine
```
### On Flox
On Flox, hyperfine can be installed as follows.
```
flox install hyperfine
```
Hyperfine's version in Flox follows that of Nix.
### On openSUSE
On openSUSE, hyperfine can be installed [from the official repositories](https://software.opensuse.org/package/hyperfine):

View File

@ -1,20 +1,20 @@
use std::collections::BTreeMap;
use serde::Serialize;
use serde::{Deserialize, Serialize};
use crate::util::units::Second;
/// Set of values that will be exported.
// NOTE: `serde` is used for JSON serialization, but not for CSV serialization due to the
// `parameters` map. Update `src/hyperfine/export/csv.rs` with new fields, as appropriate.
#[derive(Debug, Default, Clone, Serialize, PartialEq)]
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
pub struct BenchmarkResult {
/// The full command line of the program that is being benchmarked
pub command: String,
/// The full command line of the program that is being benchmarked, possibly including a list of
/// parameters that were not used in the command line template.
#[serde(skip_serializing)]
#[serde(skip)]
pub command_with_unused_parameters: String,
/// The average run time
@ -46,6 +46,6 @@ pub struct BenchmarkResult {
pub exit_codes: Vec<Option<i32>>,
/// Parameter values for this benchmark
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub parameters: BTreeMap<String, String>,
}

View File

@ -22,12 +22,13 @@ impl<'a> Scheduler<'a> {
commands: &'a Commands,
options: &'a Options,
export_manager: &'a ExportManager,
results: &'a Vec<BenchmarkResult>,
) -> Self {
Self {
commands,
options,
export_manager,
results: vec![],
results: results.to_vec(),
}
}
@ -69,6 +70,14 @@ impl<'a> Scheduler<'a> {
&self.results,
self.options.sort_order_speed_comparison,
) {
fn get_command_from_result<'b>(result: &'b BenchmarkResult) -> &'b str {
if !result.command_with_unused_parameters.is_empty() {
&result.command_with_unused_parameters
} else {
&result.command
}
}
match self.options.sort_order_speed_comparison {
SortOrder::MeanTime => {
println!("{}", "Summary".bold());
@ -78,7 +87,7 @@ impl<'a> Scheduler<'a> {
println!(
" {} ran",
fastest.result.command_with_unused_parameters.cyan()
(get_command_from_result(&fastest.result)).cyan()
);
for item in others {
@ -90,7 +99,8 @@ impl<'a> Scheduler<'a> {
} else {
"".into()
},
&item.result.command_with_unused_parameters.magenta()
// &item.result.command_with_unused_parameters.magenta()
&(get_command_from_result(&item.result)).magenta()
);
}
}
@ -108,7 +118,7 @@ impl<'a> Scheduler<'a> {
} else {
" ".into()
},
&item.result.command_with_unused_parameters,
&(get_command_from_result(item.result)),
);
}
}

View File

@ -283,6 +283,13 @@ fn build_command() -> Command {
.help("Export the timing summary statistics and timings of individual runs as JSON to the given FILE. \
The output time unit is always seconds"),
)
.arg(
Arg::new("import-json")
.long("import-json")
.action(ArgAction::Set)
.value_name("FILE")
.help("Import the timing summary statistics and timings of individual runs from a JSON FILE.")
)
.arg(
Arg::new("export-markdown")
.long("export-markdown")

View File

@ -8,9 +8,9 @@ use crate::util::units::Unit;
use anyhow::Result;
#[derive(Serialize, Debug)]
struct HyperfineSummary<'a> {
results: &'a [BenchmarkResult],
#[derive(Serialize, Deserialize, Debug)]
pub struct HyperfineSummary {
pub results: Vec<BenchmarkResult>,
}
#[derive(Default)]
@ -23,7 +23,9 @@ impl Exporter for JsonExporter {
_unit: Option<Unit>,
_sort_order: SortOrder,
) -> Result<Vec<u8>> {
let mut output = to_vec_pretty(&HyperfineSummary { results });
let mut output = to_vec_pretty(&HyperfineSummary {
results: results.to_vec(),
});
if let Ok(ref mut content) = output {
content.push(b'\n');
}

View File

@ -3,7 +3,7 @@ use std::io::Write;
mod asciidoc;
mod csv;
mod json;
pub mod json;
mod markdown;
mod markup;
mod orgmode;

31
src/import.rs Normal file
View File

@ -0,0 +1,31 @@
use crate::{benchmark::benchmark_result::BenchmarkResult, export::json::HyperfineSummary};
use clap::ArgMatches;
use std::fs;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Importer {}
impl Importer {
pub fn from_cli_arguments(matches: &ArgMatches) -> Option<Vec<BenchmarkResult>> {
match matches.get_one::<String>("import-json") {
Some(file_name) => read_summary_from_file(file_name),
None => None,
}
}
}
fn read_summary_from_file(file_name: &str) -> Option<Vec<BenchmarkResult>> {
let file_content = match fs::read_to_string(file_name) {
Ok(content) => content,
Err(_) => {
eprintln!("Unable to load previous run from file {}", file_name);
return None;
}
};
let hyperfine_summary = serde_json::from_str::<HyperfineSummary>(&file_content);
match hyperfine_summary {
Ok(summary) => Some(summary.results),
Err(_) => None,
}
}

View File

@ -9,6 +9,7 @@ use benchmark::scheduler::Scheduler;
use cli::get_cli_arguments;
use command::Commands;
use export::ExportManager;
use import::Importer;
use options::Options;
use anyhow::Result;
@ -19,6 +20,7 @@ pub mod cli;
pub mod command;
pub mod error;
pub mod export;
pub mod import;
pub mod options;
pub mod outlier_detection;
pub mod output;
@ -32,13 +34,15 @@ fn run() -> Result<()> {
colored::control::set_virtual_terminal(true).unwrap();
let cli_arguments = get_cli_arguments(env::args_os());
let previous_results = Importer::from_cli_arguments(&cli_arguments).unwrap_or(Vec::new());
let options = Options::from_cli_arguments(&cli_arguments)?;
let commands = Commands::from_cli_arguments(&cli_arguments)?;
let export_manager = ExportManager::from_cli_arguments(&cli_arguments, options.time_unit)?;
options.validate_against_command_list(&commands)?;
let mut scheduler = Scheduler::new(&commands, &options, &export_manager);
let mut scheduler = Scheduler::new(&commands, &options, &export_manager, &previous_results);
scheduler.run_benchmarks()?;
scheduler.print_relative_speed_comparison();
scheduler.final_export()?;