Compare commits

..
Author SHA1 Message Date
David Peter 12fec42098 Update README.md 2024-11-11 22:41:35 +01:00
David Peter 564ccafb03 Preparations for v1.19 2024-11-11 22:39:30 +01:00
David Peter 99d24b7a2e Multiple output policies 2024-11-11 22:24:25 +01:00
David Carlier 2899deb8fd apply clippy advices on executor/commands lifetimes. 2024-11-11 08:47:33 +01:00
David Peter 74615f01fb Update README.md
This reverts commit 09c39d8989.
2024-11-11 08:30:58 +01:00
rindeal 83edd2f8e3 Update CICD.yml 2024-11-10 23:00:44 +01:00
David Peter 2efc633486 Update dependencies 2024-11-10 22:57:23 +01:00
David Peter 83f04cdd31 Add iteration information to failure error message 2024-11-10 22:26:13 +01:00
David Carlier f096c266f0 fix build warning proposal
```rust
warning: elided lifetime has a name
   --> src/command.rs:137:66
    |
136 | impl<'a> Commands<'a> {
    |      -- lifetime `'a` declared here
137 |     pub fn from_cli_arguments(matches: &'a ArgMatches) -> Result<Commands> {
    |                                                                  ^^^^^^^^ this elided lifetime gets resolved as `'
```
2024-11-10 20:45:03 +01:00
David Peter e3e86174d9 Minor rewording 2024-08-28 17:26:40 +02:00
17 changed files with 469 additions and 513 deletions

No files matched your search

+16 -7
View File
@@ -22,17 +22,25 @@ jobs:
- name: Extract crate information
id: crate_metadata
run: |
cargo metadata --no-deps --format-version 1 | jq -r '"name=" + .packages[0].name' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"version=" + .packages[0].version' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"maintainer=" + .packages[0].authors[0]' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"homepage=" + .packages[0].homepage' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '"msrv=" + .packages[0].rust_version' | tee -a $GITHUB_OUTPUT
cargo metadata --no-deps --format-version 1 | jq -r '
.packages[0] |
[
"name=" + .name,
"version=" + .version,
"maintainer=" + (.authors[0] // ""),
"homepage=" + (.homepage // ""),
"msrv=" + (.rust_version // ""),
"bin-name=" + ( (.targets[] | select(.kind[0] == "bin") | .name) // .name )
] |
join("\n")
' | tee -a $GITHUB_OUTPUT
outputs:
name: ${{ steps.crate_metadata.outputs.name }}
version: ${{ steps.crate_metadata.outputs.version }}
maintainer: ${{ steps.crate_metadata.outputs.maintainer }}
homepage: ${{ steps.crate_metadata.outputs.homepage }}
msrv: ${{ steps.crate_metadata.outputs.msrv }}
bin-name: ${{ steps.crate_metadata.outputs.bin-name }}
ensure_cargo_fmt:
name: Ensure 'cargo fmt' has been run
@@ -115,6 +123,7 @@ jobs:
- name: Show version information (Rust, cargo, GCC)
shell: bash
run: |
set -x
gcc --version || true
rustup -V
rustup toolchain list
@@ -137,7 +146,7 @@ jobs:
esac;
# Setup paths
BIN_NAME="${{ needs.crate_metadata.outputs.name }}${EXE_suffix}"
BIN_NAME="${{ needs.crate_metadata.outputs.bin-name }}${EXE_suffix}"
BIN_PATH="target/${{ matrix.job.target }}/release/${BIN_NAME}"
# Let subsequent steps know where to find the binary
@@ -150,7 +159,7 @@ jobs:
run: |
# test only library unit tests and binary for arm-type targets
unset CARGO_TEST_OPTIONS
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--bin ${{ needs.crate_metadata.outputs.name }}" ;; esac;
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--bin ${{ steps.bin.outputs.BIN_NAME }}" ;; esac;
echo "CARGO_TEST_OPTIONS=${CARGO_TEST_OPTIONS}" >> $GITHUB_OUTPUT
- name: Run tests
+13 -5
View File
@@ -1,17 +1,25 @@
# unreleased
# v1.19.0
## Features
## Changes
- Add a new `--reference <cmd>` option to specify a reference command for the relative speed comparison, see #579, #577 and #744 (@sharkdp)
- Add `--conclude` argument (analog to `--prepare`), see #565 and #719 (@jackoconnordev)
- Allow `--output=…` to appear once for each command, enabling use cases like `hyperfine --output=null my-cmd --output=./file.log my-cmd`, see #529 and #775 (@sharkdp)
- The environment variable `$HYPERFINE_ITERATION` will now contain the current iteration number for each benchmarked command, see #775 (@sharkdp)
- Add iteration information to failure error message, see #771 and #772 (@sharkdp)
- Python scripts:
- legend modification parameters and output DPI, see #758 (@Spreadcat)
- Nicer whiskers plot, see #727 (@serpent7776)
## Bugfixes
- ETA not clearly visible on terminals with a block cursor, see #698 and #699 (@overclockworked64)
- Fix zsh completions, see #717 (@xzfc)
## Other
- Build binaries for aarch64-apple-darwin, see #728 (@Phault)
- Various cleanups (@hamirmahal, @one230six)
# v1.18.0
Generated
+244 -315
View File
File diff suppressed because it is too large. Load diff
+17 -9
View File
@@ -7,10 +7,10 @@ license = "MIT OR Apache-2.0"
name = "hyperfine"
readme = "README.md"
repository = "https://github.com/sharkdp/hyperfine"
version = "1.18.0"
version = "1.19.0"
edition = "2018"
build = "build.rs"
rust-version = "1.70.0"
rust-version = "1.76.0"
[features]
# Use the nightly feature windows_process_extensions_main_thread_handle
@@ -20,20 +20,20 @@ windows_process_extensions_main_thread_handle = []
colored = "2.1"
indicatif = "=0.17.4"
statistical = "1.0"
csv = "1.1"
csv = "1.3"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rust_decimal = "1.35"
rust_decimal = "1.36"
rand = "0.8"
shell-words = "1.0"
thiserror = "1.0"
thiserror = "2.0"
anyhow = "1.0"
[target.'cfg(not(windows))'.dependencies]
libc = "0.2"
[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.48", features = [
windows-sys = { version = "0.59", features = [
"Win32_Foundation",
"Win32_Security",
"Win32_System_JobObjects",
@@ -45,18 +45,26 @@ windows-sys = { version = "0.48", features = [
once_cell = "1.19"
[target.'cfg(target_os="linux")'.dependencies]
nix = { version = "0.27.1", features = ["zerocopy"] }
nix = { version = "0.29", features = ["zerocopy"] }
[dependencies.clap]
version = "4"
default-features = false
features = ["suggestions", "color", "wrap_help", "cargo", "help", "usage", "error-context"]
features = [
"suggestions",
"color",
"wrap_help",
"cargo",
"help",
"usage",
"error-context",
]
[dev-dependencies]
approx = "0.5"
assert_cmd = "2.0"
predicates = "3.0"
tempfile = "3.9"
tempfile = "3.14"
[build-dependencies]
clap = "4.4.12"
+2 -17
View File
@@ -10,21 +10,6 @@ A command-line benchmarking tool.
![hyperfine](https://i.imgur.com/z19OYxE.gif)
## Sponsors
A special *thank you* goes to our biggest <a href="doc/sponsors.md">sponsor</a>:
<a href="https://bencher.dev/hyperfine/?utm_source=github&utm_medium=referral&utm_campaign=hyperfine&utm_content=wordmark">
<img src="doc/sponsors/bencher_wordmark.svg" width="200" alt="🐰 Bencher">
<br />
<strong>Continuous Benchmarking: Catch performance regressions in CI</strong>
</a>
<br />
<br />
Track the results of your <code>hyperfine</code> benchmarks over time with Bencher. \
Detect and prevent performance regressions before they make it to production.
## Features
* Statistical analysis across multiple runs.
@@ -178,7 +163,7 @@ like `--warmup`, `--prepare <cmd>`, `--setup <cmd>` or `--cleanup <cmd>`:
## Installation
[![Packaging status](https://repology.org/badge/vertical-allrepos/hyperfine.svg)](https://repology.org/project/hyperfine/versions)
[![Packaging status](https://repology.org/badge/vertical-allrepos/hyperfine.svg?columns=3&exclude_unsupported=1)](https://repology.org/project/hyperfine/versions)
### On Ubuntu
@@ -316,7 +301,7 @@ Hyperfine can be installed from source via [cargo](https://doc.rust-lang.org/car
cargo install --locked hyperfine
```
Make sure that you use Rust 1.70 or newer.
Make sure that you use Rust 1.76 or newer.
### From binaries (Linux, macOS, Windows)
+5
View File
@@ -290,6 +290,11 @@ Don't redirect the output at all (same as \&'\-\-show\-output').
.IP "<FILE>"
Write the output to the given file.
.RE
.IP
This option can be specified once for all commands or multiple times,
once for each command. Note: If you want to log the output of each and
every iteration, you can use a shell redirection and the $HYPERFINE_ITERATION
environment variable: 'my-command > output-${HYPERFINE_ITERATION}.log'
.HP
\fB\-\-input\fR \fIWHERE\fP
.IP
-12
View File
@@ -1,12 +0,0 @@
## Sponsors
`hyperfine` development is sponsored by many individuals and companies. Thank you very much!
Please note, that being sponsored does not affect the individuality of the `hyperfine`
project or affect the maintainers' actions in any way.
We remain impartial and continue to assess pull requests solely on merit - the
features added, bugs solved, and effect on the overall complexity of the code.
No issue will have a different priority based on sponsorship status of the
reporter.
If you want to see our biggest sponsors, check the top of [`README.md`](../README.md#sponsors).
-80
View File
@@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="bencher_wordmark"
version="1.1"
viewBox="0 0 600 113"
sodipodi:docname="bencher_wordmark.svg"
inkscape:version="1.3 (0e150ed, 2023-07-21)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="256"
inkscape:cx="0.09765625"
inkscape:cy="80.701172"
inkscape:window-width="1672"
inkscape:window-height="1278"
inkscape:window-x="672"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="bencher_wordmark" />
<rect
style="fill:#ffffff;stroke-width:8.58435"
id="rect1"
width="600"
height="113"
x="0.00028267503"
y="0"
inkscape:label="background" />
<path
id="outline"
fill="#000000"
fill-opacity="1"
d="m 87.04,54.87 c 5.413333,4.24 9.113333,9.476667 11.1,15.71 1.853333,5.786667 2.15333,11.436667 0.9,16.95 -1.366667,6.013333 -4.61,11.023333 -9.73,15.03 -4.386667,3.44 -9.736667,5.77333 -16.05,7 -9.833333,1.91333 -19.61,1.67 -29.33,-0.73 -4.053333,-1 -7.823333,-2.63667 -11.31,-4.91 C 27.826667,100.78667 24.42,96.77 22.4,91.87 20.553333,87.363333 19.95,82.366667 20.59,76.88 21.583333,68.446667 25.623333,61.153333 32.71,55 c 0.602958,-0.526584 0.745946,-1.405539 0.34,-2.09 -4.04,-6.76 -7.213333,-14.043333 -9.52,-21.85 -1.38,-4.673333 -1.906667,-8.61 -1.58,-11.81 0.433333,-4.353333 1.97,-8.166667 4.61,-11.44 3.16,-3.9133333 7.056667,-5.7966667 11.69,-5.65 3.92,0.12 7.6,1.59 11.04,4.41 4.6,3.78 7.336667,7.42904 8.21,13.935707 0.49,3.643333 0.657432,5.952996 0.865387,10.739823 0.150482,3.522425 0.111596,7.280575 0.07402,10.602405 -0.04773,1.205311 -0.01116,2.062877 0.193426,2.394139 0.734393,1.130752 2.423841,1.054593 2.837174,-0.09207 0.153333,-0.433333 0.206667,-1.17 0.16,-2.21 -0.18,-3.6 -0.183333,-7.2 -0.01,-10.8 0.24,-5.093333 0.56,-8.676667 0.96,-10.75 1.48,-7.68 5.723333,-13.29 12.73,-16.83 3.4,-1.7133333 6.866667,-2.0133333 10.4,-0.9 2.98,0.9466667 5.603333,2.8733333 7.87,5.78 3.333333,4.28 4.866667,9.083333 4.6,14.41 -0.186667,3.64 -1.616667,8.863333 -4.29,15.67 -1.973333,5.046667 -4.36,9.94 -7.16,14.68 -0.326572,0.559373 -0.194376,1.271522 0.31,1.67 z m -20.85,-5 C 62.283333,49.383333 58.143333,49.37 53.77,49.83 53.447244,49.8578 53.180693,49.581558 53.22,49.26 54.473333,39.493333 54.316667,29.99 52.75,20.75 52.323333,18.23 51.266667,15.79 49.58,13.43 48.033333,11.256667 46.086667,9.56 43.74,8.34 37.9,5.2933333 33.136667,6.4366667 29.45,11.77 c -1.406667,2.033333 -2.343333,4.356667 -2.81,6.97 -0.5,2.84 -0.443333,5.406667 0.17,7.7 2.666667,9.866667 6.923333,19.276667 12.77,28.23 0.173388,0.265249 0.09631,0.618913 -0.17,0.78 -5.8,3.666667 -9.92,8.423333 -12.36,14.27 -2.48,5.953333 -2.926667,11.89 -1.34,17.81 2.006667,7.5 7.123333,12.72 15.35,15.66 11.58,4.13333 23.636667,4.3 36.17,0.5 7.873333,-2.38667 13.18,-6.823333 15.92,-13.31 2.513333,-5.953333 2.663333,-12.243333 0.45,-18.87 -2.193333,-6.54 -6.52,-11.856667 -12.98,-15.95 -0.308104,-0.194766 -0.398356,-0.600899 -0.2,-0.9 5.073333,-7.793333 8.956667,-15.926667 11.65,-24.4 0.96,-3.04 1.486667,-5.63 1.58,-7.77 0.126667,-3.086667 -0.36,-5.73 -1.46,-7.93 -3.346667,-6.6533333 -7.873333,-9.07 -13.58,-7.25 -3.566667,1.1333333 -6.43,3.433333 -8.59,6.9 -2.013333,3.226667 -3.186667,6.906667 -3.52,11.04 -0.68,8.426667 -0.633333,16.486667 0.14,24.18 0.02818,0.257891 -0.192807,0.473963 -0.45,0.44 z" />
<path
id="face"
d="m 37.625,6.6796875 c -0.314528,0.00599 -0.625523,0.029637 -0.931641,0.068359 -0.306116,0.038724 -0.608544,0.092604 -0.90625,0.1640625 -0.297704,0.071458 -0.591565,0.1594803 -0.880859,0.2636718 -0.289294,0.1041917 -0.574586,0.2244025 -0.855469,0.3613282 -0.280882,0.1369257 -0.555653,0.2912777 -0.828125,0.4609375 -0.27247,0.1696597 -0.542581,0.3542468 -0.80664,0.5566406 -0.264061,0.2023938 -0.523649,0.4211222 -0.779297,0.65625 -0.255649,0.2351278 -0.506669,0.4879974 -0.753907,0.7558594 -0.247236,0.2678625 -0.489689,0.5509675 -0.728515,0.8515625 -0.238826,0.300597 -0.474664,0.617843 -0.705078,0.951172 -0.351663,0.508329 -0.673884,1.035501 -0.966797,1.580078 -0.292914,0.544579 -0.554898,1.106673 -0.789063,1.6875 -0.234163,0.580828 -0.439819,1.179798 -0.615234,1.796875 -0.175415,0.617078 -0.320835,1.252924 -0.4375,1.90625 -0.124998,0.709994 -0.216069,1.402299 -0.271484,2.078125 -0.05542,0.675827 -0.07667,1.334902 -0.0625,1.976563 0.01417,0.64166 0.06469,1.265553 0.148437,1.873047 0.08375,0.607494 0.202137,1.198157 0.355469,1.771484 0.33333,1.233321 0.691202,2.460637 1.074219,3.679688 0.383017,1.21905 0.789952,2.429986 1.222656,3.634765 0.432704,1.20478 0.890655,2.403241 1.373047,3.59375 0.48239,1.190509 0.989406,2.374543 1.521484,3.550781 0.532078,1.17624 1.09011,2.343893 1.671875,3.50586 0.581765,1.161967 1.186908,2.317146 1.818359,3.464844 0.631453,1.147696 1.289564,2.288448 1.970704,3.421875 0.681138,1.133425 1.386361,2.25975 2.117187,3.378906 0.04143,0.06285 0.06999,0.133262 0.08398,0.207031 0.0136,0.07397 0.01226,0.149706 -0.0039,0.222656 -0.01615,0.07267 -0.04671,0.141089 -0.08984,0.201172 -0.04283,0.05992 -0.09729,0.110398 -0.160156,0.148438 -0.724992,0.458328 -1.423209,0.935344 -2.095703,1.427734 -0.672494,0.492391 -1.319459,1.000891 -1.939453,1.527344 -0.619994,0.526453 -1.213756,1.070344 -1.78125,1.630859 -0.567494,0.560515 -1.108051,1.137845 -1.623047,1.732422 -0.514994,0.594577 -1.004301,1.205346 -1.466797,1.833984 -0.462494,0.62864 -0.898598,1.274799 -1.308594,1.9375 -0.409994,0.662703 -0.794847,1.342299 -1.152343,2.039063 -0.357496,0.696764 -0.68719,1.411752 -0.992188,2.142578 -0.309996,0.744159 -0.589481,1.486831 -0.835937,2.230469 -0.246456,0.743638 -0.461616,1.48735 -0.644532,2.230469 -0.182914,0.743117 -0.33375,1.485919 -0.453125,2.228515 -0.119373,0.742598 -0.205886,1.484486 -0.261718,2.226563 -0.05583,0.742075 -0.07997,1.485007 -0.07227,2.226562 0.0077,0.741556 0.04594,1.481623 0.117188,2.222656 0.07125,0.741035 0.175757,1.482143 0.310546,2.222657 0.134791,0.740513 0.301669,1.480711 0.5,2.220703 0.125417,0.468746 0.262398,0.929927 0.41211,1.380859 0.149712,0.450933 0.310366,0.893051 0.484375,1.326172 0.174008,0.433121 0.360288,0.856177 0.558594,1.271484 0.198305,0.415309 0.41021,0.821254 0.632812,1.21875 0.222602,0.397498 0.456226,0.786333 0.703125,1.166016 0.246899,0.379684 0.506148,0.75141 0.777344,1.113281 0.271195,0.361873 0.554118,0.714535 0.849609,1.058594 0.295493,0.344059 0.60404,0.679613 0.923828,1.005859 0.319789,0.326248 0.652009,0.642738 0.996094,0.951172 0.344085,0.308435 0.699978,0.607815 1.068359,0.898438 0.368383,0.290621 0.747947,0.572893 1.140625,0.845703 0.39268,0.272815 0.797869,0.536015 1.214844,0.791015 0.416975,0.255 0.845838,0.5011 1.28711,0.73828 0.44127,0.23719 0.895759,0.46617 1.361328,0.68555 0.465567,0.21937 0.943729,0.4293 1.433593,0.63086 0.489866,0.20156 0.991698,0.39437 1.50586,0.57812 0.723742,0.25834 1.448315,0.50118 2.175781,0.72852 0.727466,0.22734 1.458263,0.44036 2.189453,0.63672 0.731192,0.19635 1.464305,0.37565 2.199219,0.54101 0.734914,0.16537 1.470346,0.3168 2.208984,0.45118 0.73864,0.13436 1.480294,0.25208 2.222657,0.35546 0.742362,0.10339 1.486335,0.19128 2.232421,0.26368 0.746088,0.0724 1.494331,0.13046 2.244141,0.17187 0.74981,0.0414 1.500372,0.0658 2.253906,0.0762 0.753535,0.0104 1.510321,0.007 2.267578,-0.0137 0.757259,-0.0206 1.516362,-0.0578 2.277344,-0.10937 0.760982,-0.0516 1.522403,-0.11862 2.28711,-0.20118 0.764705,-0.0825 1.532351,-0.17943 2.300781,-0.29296 0.76843,-0.11355 1.538393,-0.24415 2.310547,-0.38868 0.772153,-0.14453 1.546388,-0.30299 2.322265,-0.47851 0.775878,-0.17552 1.55243,-0.36771 2.332032,-0.57422 0.779601,-0.20651 1.562377,-0.42852 2.345703,-0.66602 0.492078,-0.14916 0.973286,-0.30552 1.445312,-0.4707 0.472027,-0.16518 0.934744,-0.33833 1.386719,-0.51953 0.451975,-0.1812 0.894249,-0.37115 1.326172,-0.56836 0.431923,-0.19721 0.853754,-0.40202 1.265625,-0.61523 0.411871,-0.21323 0.813259,-0.43482 1.205078,-0.66407 0.391819,-0.22924 0.772764,-0.46569 1.144531,-0.71093 0.371767,-0.245268 0.734223,-0.498497 1.085938,-0.759771 0.351715,-0.261272 0.693727,-0.531305 1.02539,-0.808593 0.331664,-0.27729 0.653233,-0.562165 0.964844,-0.855469 0.311612,-0.293305 0.612737,-0.594978 0.904297,-0.904297 0.29156,-0.309319 0.574195,-0.625837 0.845703,-0.951172 0.271508,-0.325335 0.531748,-0.658649 0.783203,-1 0.251456,-0.34135 0.493206,-0.691462 0.72461,-1.048828 0.231403,-0.357366 0.45271,-0.722322 0.664062,-1.095703 0.211352,-0Line truncated
style="fill:#ffffff" />
<path
id="mouth"
fill="#bfb5bf"
fill-opacity="1"
d="m 65,95.56 q 2.08,0 3.57,-1.6 0.21,-0.24 0.41,-0.35 1.2,-0.71 0.21,0.83 -2.88,4.47 -8.66,1.9 a 1.22,1.23 46.3 0 0 -0.95,-0.02 q -6.21,2.54 -8.93,-2.26 -0.42,-0.74 0.05,-0.71 a 1.04,0.54 59.1 0 1 0.6,0.37 q 3.6,4.14 7.61,-0.87 a 1.32,1.32 0 0 1 2.22,0.26 q 0.46,0.98 1.65,1.76 1.06,0.69 2.22,0.69 z" />
<ellipse
id="nose"
fill="#fc7300"
fill-opacity="1"
cx="60.445126"
cy="88.674728"
rx="3.53"
ry="1.97"
transform="rotate(0.3)" />
<path
id="ears"
fill="#fc7300"
fill-opacity="1"
d="m 42.15,15.69 c 0.733333,0.553333 1.346667,1.216667 1.84,1.99 1.933333,3.046667 3.033333,6.736667 3.3,11.07 0.366667,6.166667 0.33,12.673333 -0.11,19.52 -0.186667,2.98 -1.19,3.286667 -3.01,0.92 -4.42,-5.753333 -7.956667,-12.92 -10.61,-21.5 -0.84,-2.726667 -0.876667,-5.523333 -0.11,-8.39 0.58,-2.153333 1.433333,-3.646667 2.56,-4.48 1.666667,-1.24 3.713333,-0.95 6.14,0.87 z m 35.7,0 c -0.733333,0.553333 -1.346667,1.216667 -1.84,1.99 -1.933333,3.046667 -3.033333,6.736667 -3.3,11.07 -0.366667,6.166667 -0.33,12.673333 0.11,19.52 0.186667,2.98 1.19,3.286667 3.01,0.92 4.42,-5.753333 7.956667,-12.92 10.61,-21.5 0.84,-2.726667 0.876667,-5.523333 0.11,-8.39 -0.58,-2.153333 -1.433333,-3.646667 -2.56,-4.48 -1.666667,-1.24 -3.713333,-0.95 -6.14,0.87 z" />
<path
id="cheeks"
style="fill:#fdb07e;fill-opacity:1"
d="m 42.084458,84.719032 c 0,3.872338 -3.278533,7.011488 -7.322808,7.011488 -4.044275,0 -7.322808,-3.13915 -7.322808,-7.011488 0,-3.872337 3.278533,-7.011487 7.322808,-7.011487 4.044275,0 7.322808,3.13915 7.322808,7.011487 z m 35.831084,0 c 0,3.872338 3.278533,7.011488 7.322808,7.011488 4.044275,0 7.322808,-3.13915 7.322808,-7.011488 0,-3.872337 -3.278533,-7.011487 -7.322808,-7.011487 -4.044275,0 -7.322808,3.13915 -7.322808,7.011487 z" />
<path
id="eyes"
style="fill:#000000;fill-opacity:1"
d="m 47.451446,76.183212 c 0,3.131826 -2.549593,5.670672 -5.694675,5.670672 -3.145082,0 -5.694674,-2.538846 -5.694674,-5.670672 0,-3.131825 2.549592,-5.670671 5.694674,-5.670671 3.145082,0 5.694675,2.538846 5.694675,5.670671 z m 25.097108,0 c 0,3.131826 2.549593,5.670672 5.694675,5.670672 3.145082,0 5.694674,-2.538846 5.694674,-5.670672 0,-3.131825 -2.549592,-5.670671 -5.694674,-5.670671 -3.145082,0 -5.694675,2.538846 -5.694675,5.670671 z" />
<path
id="bencher"
style="font-size:112.596px;fill:#000000;stroke-width:9.38295"
d="m 417.35352,12 v 85.544924 h 10.33593 V 51.69336 c 2.82223,-2.162487 5.77277,-3.939244 8.85157,-5.332032 3.07879,-1.392787 6.02933,-2.089843 8.85156,-2.089843 2.74892,0 4.98437,0.384598 6.70703,1.154297 1.72266,0.733046 3.04268,1.868806 3.95899,3.408203 0.87965,1.392787 1.48458,3.335768 1.81445,5.828125 0.32987,2.455704 0.49414,5.095741 0.49414,7.917968 v 34.964846 h 10.33594 V 57.685547 c 0,-7.513723 -1.74069,-13.266617 -5.22266,-17.261719 -3.48197,-3.995101 -8.53976,-5.99414 -15.17383,-5.99414 -3.62858,0 -7.16601,0.751161 -10.61133,2.253906 -3.44531,1.502745 -6.78045,3.59196 -10.00586,6.267578 V 12 Z M 144,15.683594 v 81.86133 h 29.0293 c 5.68111,0 10.3543,-0.5128 14.01953,-1.53906 3.70188,-1.026269 7.09113,-2.748921 10.16992,-5.167973 2.60232,-2.015877 4.6735,-4.58182 6.21289,-7.697266 1.5394,-3.115446 2.3086,-6.706984 2.3086,-10.77539 0,-5.681108 -1.5925,-10.372336 -4.78125,-14.074219 -3.18875,-3.738535 -7.55144,-6.176279 -13.08594,-7.3125 v -0.439453 c 3.29871,-1.649354 5.93874,-3.830698 7.91797,-6.542969 1.97922,-2.748923 2.96875,-6.066027 2.96875,-9.951172 0,-3.445317 -0.67902,-6.395858 -2.03516,-8.851562 -1.35613,-2.492357 -3.53748,-4.525514 -6.54297,-6.101563 -2.71227,-1.392788 -5.55264,-2.310172 -8.52148,-2.75 -2.96884,-0.439828 -7.43974,-0.658203 -13.41406,-0.658203 z m 10.88672,9.291016 h 12.97461 c 3.62858,0 6.67125,0.128199 9.12695,0.384765 2.45571,0.219914 4.54492,0.824841 6.26758,1.814453 1.46609,0.843003 2.52776,1.942693 3.1875,3.298828 0.65974,1.356136 0.99024,3.022729 0.99024,5.001954 0,2.3824 -0.36657,4.453579 -1.09961,6.21289 -0.6964,1.722659 -1.90625,3.132853 -3.62891,4.232422 -1.72266,1.099569 -3.59154,1.832696 -5.60742,2.199219 -2.01588,0.329871 -4.72806,0.496094 -8.13672,0.496094 h -14.07422 z m 90.98828,9.455078 c -8.94316,0 -16.16231,2.950541 -21.66015,8.851562 -5.4612,5.901022 -8.19336,13.873284 -8.19336,23.916016 0,10.152689 2.86036,17.996751 8.57812,23.53125 5.71776,5.497848 13.67003,8.246098 23.85938,8.246098 3.9951,0 7.80696,-0.49477 11.43554,-1.48438 3.62858,-0.98961 7.18405,-2.217501 10.66602,-3.683593 V 82.53711 h -0.54883 c -1.79596,1.612701 -4.8206,3.261259 -9.07227,4.947265 -4.21501,1.649354 -8.41148,2.47461 -12.58984,2.47461 -3.1521,0 -6.04853,-0.440657 -8.6875,-1.320313 -2.60231,-0.879655 -4.8558,-2.19772 -6.76172,-3.957031 -1.97922,-1.795963 -3.5376,-4.087472 -4.67383,-6.873047 -1.13622,-2.822228 -1.70312,-6.121297 -1.70312,-9.896484 h 45.24609 v -5.607422 c 0,-8.906511 -2.25348,-15.779083 -6.76172,-20.617188 -4.47158,-4.838104 -10.84939,-7.257812 -19.13281,-7.257812 z m 72.51758,0 c -3.62858,0 -7.16601,0.751161 -10.61133,2.253906 -3.44532,1.502745 -6.78045,3.59196 -10.00586,6.267578 v -6.816406 h -10.33594 v 61.410158 h 10.33594 V 51.69336 c 2.82223,-2.162487 5.77277,-3.939244 8.85156,-5.332032 3.0788,-1.392787 6.02934,-2.089843 8.85157,-2.089843 2.74892,0 4.98437,0.384598 6.70703,1.154297 1.72266,0.733046 3.04268,1.868806 3.95898,3.408203 0.87966,1.392787 1.48459,3.335768 1.81446,5.828125 0.32987,2.455704 0.49414,5.095741 0.49414,7.917968 v 34.964846 h 10.33593 V 57.685547 c 0,-7.513723 -1.74068,-13.266617 -5.22265,-17.261719 -3.48197,-3.995101 -8.53976,-5.99414 -15.17383,-5.99414 z m 195.72266,0 c -8.94317,0 -16.16231,2.950541 -21.66016,8.851562 -5.46119,5.901022 -8.19336,13.873284 -8.19336,23.916016 0,10.152689 2.86037,17.996751 8.57813,23.53125 5.71776,5.497848 13.67003,8.246098 23.85937,8.246098 3.9951,0 7.80697,-0.49477 11.43555,-1.48438 3.62858,-0.98961 7.18404,-2.217501 10.66601,-3.683593 V 82.53711 h -0.54883 c -1.79596,1.612701 -4.82059,3.261259 -9.07226,4.947265 -4.21502,1.649354 -8.41148,2.47461 -12.58984,2.47461 -3.1521,0 -6.04854,-0.440657 -8.6875,-1.320313 -2.60232,-0.879655 -4.8558,-2.19772 -6.76172,-3.957031 -1.97923,-1.795963 -3.53761,-4.087472 -4.67383,-6.873047 -1.13622,-2.822228 -1.70313,-6.121297 -1.70313,-9.896484 h 45.2461 v -5.607422 c 0,-8.906511 -2.25349,-15.779083 -6.76172,-20.617188 -4.47158,-4.838104 -10.84939,-7.257812 -19.13281,-7.257812 z m -129.69336,0.27539 c -9.05312,0 -16.34832,2.858412 -21.88282,8.576172 -5.49784,5.71776 -8.24609,13.597893 -8.24609,23.640625 0,5.387889 0.73313,10.099106 2.19922,14.13086 1.46609,4.031753 3.53727,7.366893 6.21289,10.005859 2.63897,2.638966 5.80984,4.61802 9.51172,5.9375 3.70188,1.28283 7.77015,1.92383 12.20508,1.92383 3.48197,0 6.76105,-0.45869 9.83984,-1.375 3.11545,-0.91631 6.39648,-2.198304 9.8418,-3.847658 v -11.38086 h -0.54883 c -0.7697,0.62309 -1.81528,1.374251 -3.13477,2.253907 -1.31948,0.843003 -2.72967,1.650223 -4.23242,2.419922 -1.72266,0.879655 -3.66564,1.594746 -5.82812,2.144531 -2.16249,0.549784 -4.28777,0.824219 -6.37696,0.824219 -6.01097,0 -10.68417,-1.979051 -14.01953,-5.9375 -3.29871,-3.995102 -4.94922,-9.695844 -4.94922,-17.09961 0,-7.62368 1.68659,-13.396562 5.0586,-17.318359 3.40866,-3.958449 8.04578,-5.9375 13.91015,-5.9375 3.18875,0 6.4498,0.660986 9.78516,1.980469 3.37201,1.319483 6.63501,3.206404 9.78711,5.662109 h 0.54883 V 39.81836 c -2.82223,-1.42944 -5.93704,-Line truncated
</svg>

Before

Width:  |  Height:  |  Size: 24 KiB

+1 -1
View File
@@ -9,7 +9,7 @@ hyperfine 'sleep 0.020' 'sleep 0.021' 'sleep 0.022' --export-json sleep.json
### Pre-requisites
To make these scripts work, you will need to install `numpy`, `matplotlib` and `scipy`.
To make these scripts work, you will need `numpy`, `matplotlib` and `scipy`.
If you have a Python package manager that understands [PEP-723](https://peps.python.org/pep-0723/)
inline script requirements like [`uv`](https://github.com/astral-sh/uv) or [`pipx`](https://github.com/pypa/pipx),
+53 -9
View File
@@ -16,12 +16,30 @@ use super::timing_result::TimingResult;
use anyhow::{bail, Context, Result};
use statistical::mean;
pub enum BenchmarkIteration {
NonBenchmarkRun,
Warmup(u64),
Benchmark(u64),
}
impl BenchmarkIteration {
pub fn to_env_var_value(&self) -> Option<String> {
match self {
BenchmarkIteration::NonBenchmarkRun => None,
BenchmarkIteration::Warmup(i) => Some(format!("warmup-{}", i)),
BenchmarkIteration::Benchmark(i) => Some(format!("{}", i)),
}
}
}
pub trait Executor {
/// Run the given command and measure the execution time
fn run_command_and_measure(
&self,
command: &Command<'_>,
iteration: BenchmarkIteration,
command_failure_action: Option<CmdFailureAction>,
output_policy: &CommandOutputPolicy,
) -> Result<(TimingResult, ExitStatus)>;
/// Perform a calibration of this executor. For example,
@@ -39,6 +57,7 @@ pub trait Executor {
fn run_command_and_measure_common(
mut command: std::process::Command,
iteration: BenchmarkIteration,
command_failure_action: CmdFailureAction,
command_input_policy: &CommandInputPolicy,
command_output_policy: &CommandOutputPolicy,
@@ -53,17 +72,29 @@ fn run_command_and_measure_common(
randomized_environment_offset::value(),
);
if let Some(value) = iteration.to_env_var_value() {
command.env("HYPERFINE_ITERATION", value);
}
let result = execute_and_measure(command)
.with_context(|| format!("Failed to run command '{command_name}'"))?;
if command_failure_action == CmdFailureAction::RaiseError && !result.status.success() {
let when = match iteration {
BenchmarkIteration::NonBenchmarkRun => "a non-benchmark run".to_string(),
BenchmarkIteration::Warmup(0) => "the first warmup run".to_string(),
BenchmarkIteration::Warmup(i) => format!("warmup iteration {i}"),
BenchmarkIteration::Benchmark(0) => "the first benchmark run".to_string(),
BenchmarkIteration::Benchmark(i) => format!("benchmark iteration {i}"),
};
bail!(
"{}. Use the '-i'/'--ignore-failure' option if you want to ignore this. \
"{cause} in {when}. Use the '-i'/'--ignore-failure' option if you want to ignore this. \
Alternatively, use the '--show-output' option to debug what went wrong.",
result.status.code().map_or(
cause=result.status.code().map_or(
"The process has been terminated by a signal".into(),
|c| format!("Command terminated with non-zero exit code: {c}")
)
|c| format!("Command terminated with non-zero exit code {c}")
),
);
}
@@ -80,17 +111,20 @@ impl<'a> RawExecutor<'a> {
}
}
impl<'a> Executor for RawExecutor<'a> {
impl Executor for RawExecutor<'_> {
fn run_command_and_measure(
&self,
command: &Command<'_>,
iteration: BenchmarkIteration,
command_failure_action: Option<CmdFailureAction>,
output_policy: &CommandOutputPolicy,
) -> Result<(TimingResult, ExitStatus)> {
let result = run_command_and_measure_common(
command.get_command()?,
iteration,
command_failure_action.unwrap_or(self.options.command_failure_action),
&self.options.command_input_policy,
&self.options.command_output_policy,
output_policy,
&command.get_command_line(),
)?;
@@ -129,11 +163,13 @@ impl<'a> ShellExecutor<'a> {
}
}
impl<'a> Executor for ShellExecutor<'a> {
impl Executor for ShellExecutor<'_> {
fn run_command_and_measure(
&self,
command: &Command<'_>,
iteration: BenchmarkIteration,
command_failure_action: Option<CmdFailureAction>,
output_policy: &CommandOutputPolicy,
) -> Result<(TimingResult, ExitStatus)> {
let on_windows_cmd = cfg!(windows) && *self.shell == Shell::Default("cmd.exe");
let mut command_builder = self.shell.command();
@@ -149,9 +185,10 @@ impl<'a> Executor for ShellExecutor<'a> {
let mut result = run_command_and_measure_common(
command_builder,
iteration,
command_failure_action.unwrap_or(self.options.command_failure_action),
&self.options.command_input_policy,
&self.options.command_output_policy,
output_policy,
&command.get_command_line(),
)?;
@@ -191,7 +228,12 @@ impl<'a> Executor for ShellExecutor<'a> {
for _ in 0..COUNT {
// Just run the shell without any command
let res = self.run_command_and_measure(&Command::new(None, ""), None);
let res = self.run_command_and_measure(
&Command::new(None, ""),
BenchmarkIteration::NonBenchmarkRun,
None,
&CommandOutputPolicy::Null,
);
match res {
Err(_) => {
@@ -260,7 +302,9 @@ impl Executor for MockExecutor {
fn run_command_and_measure(
&self,
command: &Command<'_>,
_iteration: BenchmarkIteration,
_command_failure_action: Option<CmdFailureAction>,
_output_policy: &CommandOutputPolicy,
) -> Result<(TimingResult, ExitStatus)> {
#[cfg(unix)]
let status = {
+54 -17
View File
@@ -6,8 +6,11 @@ pub mod timing_result;
use std::cmp;
use crate::benchmark::executor::BenchmarkIteration;
use crate::command::Command;
use crate::options::{CmdFailureAction, ExecutorKind, Options, OutputStyleOption};
use crate::options::{
CmdFailureAction, CommandOutputPolicy, ExecutorKind, Options, OutputStyleOption,
};
use crate::outlier_detection::{modified_zscores, OUTLIER_THRESHOLD};
use crate::output::format::{format_duration, format_duration_unit};
use crate::output::progress_bar::get_progress_bar;
@@ -55,9 +58,15 @@ impl<'a> Benchmark<'a> {
&self,
command: &Command<'_>,
error_output: &'static str,
output_policy: &CommandOutputPolicy,
) -> Result<TimingResult> {
self.executor
.run_command_and_measure(command, Some(CmdFailureAction::RaiseError))
.run_command_and_measure(
command,
executor::BenchmarkIteration::NonBenchmarkRun,
Some(CmdFailureAction::RaiseError),
output_policy,
)
.map(|r| r.0)
.map_err(|_| anyhow!(error_output))
}
@@ -66,6 +75,7 @@ impl<'a> Benchmark<'a> {
fn run_setup_command(
&self,
parameters: impl IntoIterator<Item = ParameterNameAndValue<'a>>,
output_policy: &CommandOutputPolicy,
) -> Result<TimingResult> {
let command = self
.options
@@ -77,7 +87,7 @@ impl<'a> Benchmark<'a> {
Append ' || true' to the command if you are sure that this can be ignored.";
Ok(command
.map(|cmd| self.run_intermediate_command(&cmd, error_output))
.map(|cmd| self.run_intermediate_command(&cmd, error_output, output_policy))
.transpose()?
.unwrap_or_default())
}
@@ -86,6 +96,7 @@ impl<'a> Benchmark<'a> {
fn run_cleanup_command(
&self,
parameters: impl IntoIterator<Item = ParameterNameAndValue<'a>>,
output_policy: &CommandOutputPolicy,
) -> Result<TimingResult> {
let command = self
.options
@@ -97,25 +108,33 @@ impl<'a> Benchmark<'a> {
Append ' || true' to the command if you are sure that this can be ignored.";
Ok(command
.map(|cmd| self.run_intermediate_command(&cmd, error_output))
.map(|cmd| self.run_intermediate_command(&cmd, error_output, output_policy))
.transpose()?
.unwrap_or_default())
}
/// Run the command specified by `--prepare`.
fn run_preparation_command(&self, command: &Command<'_>) -> Result<TimingResult> {
fn run_preparation_command(
&self,
command: &Command<'_>,
output_policy: &CommandOutputPolicy,
) -> Result<TimingResult> {
let error_output = "The preparation command terminated with a non-zero exit code. \
Append ' || true' to the command if you are sure that this can be ignored.";
self.run_intermediate_command(command, error_output)
self.run_intermediate_command(command, error_output, output_policy)
}
/// Run the command specified by `--conclude`.
fn run_conclusion_command(&self, command: &Command<'_>) -> Result<TimingResult> {
fn run_conclusion_command(
&self,
command: &Command<'_>,
output_policy: &CommandOutputPolicy,
) -> Result<TimingResult> {
let error_output = "The conclusion command terminated with a non-zero exit code. \
Append ' || true' to the command if you are sure that this can be ignored.";
self.run_intermediate_command(command, error_output)
self.run_intermediate_command(command, error_output, output_policy)
}
/// Run the benchmark for a single command
@@ -135,6 +154,8 @@ impl<'a> Benchmark<'a> {
let mut exit_codes: Vec<Option<i32>> = vec![];
let mut all_succeeded = true;
let output_policy = &self.options.command_output_policies[self.number];
let preparation_command = self.options.preparation_command.as_ref().map(|values| {
let preparation_command = if values.len() == 1 {
&values[0]
@@ -147,10 +168,11 @@ impl<'a> Benchmark<'a> {
self.command.get_parameters().iter().cloned(),
)
});
let run_preparation_command = || {
preparation_command
.as_ref()
.map(|cmd| self.run_preparation_command(cmd))
.map(|cmd| self.run_preparation_command(cmd, output_policy))
.transpose()
};
@@ -169,11 +191,11 @@ impl<'a> Benchmark<'a> {
let run_conclusion_command = || {
conclusion_command
.as_ref()
.map(|cmd| self.run_conclusion_command(cmd))
.map(|cmd| self.run_conclusion_command(cmd, output_policy))
.transpose()
};
self.run_setup_command(self.command.get_parameters().iter().cloned())?;
self.run_setup_command(self.command.get_parameters().iter().cloned(), output_policy)?;
// Warmup phase
if self.options.warmup_count > 0 {
@@ -187,9 +209,14 @@ impl<'a> Benchmark<'a> {
None
};
for _ in 0..self.options.warmup_count {
for i in 0..self.options.warmup_count {
let _ = run_preparation_command()?;
let _ = self.executor.run_command_and_measure(self.command, None)?;
let _ = self.executor.run_command_and_measure(
self.command,
BenchmarkIteration::Warmup(i),
None,
output_policy,
)?;
let _ = run_conclusion_command()?;
if let Some(bar) = progress_bar.as_ref() {
bar.inc(1)
@@ -216,7 +243,12 @@ impl<'a> Benchmark<'a> {
preparation_result.map_or(0.0, |res| res.time_real + self.executor.time_overhead());
// Initial timing run
let (res, status) = self.executor.run_command_and_measure(self.command, None)?;
let (res, status) = self.executor.run_command_and_measure(
self.command,
BenchmarkIteration::Benchmark(0),
None,
output_policy,
)?;
let success = status.success();
let conclusion_result = run_conclusion_command()?;
@@ -260,7 +292,7 @@ impl<'a> Benchmark<'a> {
}
// Gather statistics (perform the actual benchmark)
for _ in 0..count_remaining {
for i in 0..count_remaining {
run_preparation_command()?;
let msg = {
@@ -272,7 +304,12 @@ impl<'a> Benchmark<'a> {
bar.set_message(msg.to_owned())
}
let (res, status) = self.executor.run_command_and_measure(self.command, None)?;
let (res, status) = self.executor.run_command_and_measure(
self.command,
BenchmarkIteration::Benchmark(i + 1),
None,
output_policy,
)?;
let success = status.success();
times_real.push(res.time_real);
@@ -401,7 +438,7 @@ impl<'a> Benchmark<'a> {
println!(" ");
}
self.run_cleanup_command(self.command.get_parameters().iter().cloned())?;
self.run_cleanup_command(self.command.get_parameters().iter().cloned(), output_policy)?;
Ok(BenchmarkResult {
command: self.command.get_name(),
+6 -2
View File
@@ -327,7 +327,7 @@ fn build_command() -> Command {
Arg::new("output")
.long("output")
.conflicts_with("show-output")
.action(ArgAction::Set)
.action(ArgAction::Append)
.value_name("WHERE")
.help(
"Control where the output of the benchmark is redirected. Note \
@@ -343,7 +343,11 @@ fn build_command() -> Command {
\n \
inherit: Don't redirect the output at all (same as '--show-output').\n\
\n \
<FILE>: Write the output to the given file.",
<FILE>: Write the output to the given file.\n\n\
This option can be specified once for all commands or multiple times, once for \
each command. Note: If you want to log the output of each and every iteration, \
you can use a shell redirection and the '$HYPERFINE_ITERATION' environment variable:\n \
hyperfine 'my-command > output-${HYPERFINE_ITERATION}.log'\n\n",
),
)
.arg(
+4 -4
View File
@@ -134,7 +134,7 @@ impl<'a> Command<'a> {
pub struct Commands<'a>(Vec<Command<'a>>);
impl<'a> Commands<'a> {
pub fn from_cli_arguments(matches: &'a ArgMatches) -> Result<Commands> {
pub fn from_cli_arguments(matches: &'a ArgMatches) -> Result<Commands<'a>> {
let command_names = matches.get_many::<String>("command-name");
let command_strings = matches
.get_many::<String>("command")
@@ -251,8 +251,8 @@ impl<'a> Commands<'a> {
self.0.iter()
}
pub fn num_commands(&self) -> usize {
self.0.len()
pub fn num_commands(&self, has_reference_command: bool) -> usize {
self.0.len() + if has_reference_command { 1 } else { 0 }
}
/// Finds all the strings that appear multiple times in the input iterator, returning them in
@@ -383,7 +383,7 @@ fn test_get_parameterized_command_name() {
assert_eq!(cmd.get_name(), "name-quux-baz");
}
impl<'a> fmt::Display for Command<'a> {
impl fmt::Display for Command<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.get_command_line())
}
+1 -1
View File
@@ -32,7 +32,7 @@ fn run() -> Result<()> {
colored::control::set_virtual_terminal(true).unwrap();
let cli_arguments = get_cli_arguments(env::args_os());
let options = Options::from_cli_arguments(&cli_arguments)?;
let mut 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)?;
+45 -29
View File
@@ -234,8 +234,8 @@ pub struct Options {
/// Where input to the benchmarked command comes from
pub command_input_policy: CommandInputPolicy,
/// What to do with the output of the benchmarked command
pub command_output_policy: CommandOutputPolicy,
/// What to do with the output of the benchmarked commands
pub command_output_policies: Vec<CommandOutputPolicy>,
/// Which time unit to use when displaying results
pub time_unit: Option<Unit>,
@@ -257,7 +257,7 @@ impl Default for Options {
sort_order_speed_comparison: SortOrder::MeanTime,
sort_order_exports: SortOrder::Command,
executor_kind: ExecutorKind::default(),
command_output_policy: CommandOutputPolicy::Null,
command_output_policies: vec![CommandOutputPolicy::Null],
time_unit: None,
command_input_policy: CommandInputPolicy::Null,
}
@@ -320,23 +320,28 @@ impl Options {
options.cleanup_command = matches.get_one::<String>("cleanup").map(String::from);
options.command_output_policy = if matches.get_flag("show-output") {
CommandOutputPolicy::Inherit
} else if let Some(output) = matches.get_one::<String>("output").map(|s| s.as_str()) {
match output {
"null" => CommandOutputPolicy::Null,
"pipe" => CommandOutputPolicy::Pipe,
"inherit" => CommandOutputPolicy::Inherit,
arg => {
let path = PathBuf::from(arg);
if path.components().count() <= 1 {
return Err(OptionsError::UnknownOutputPolicy(arg.to_string()));
options.command_output_policies = if matches.get_flag("show-output") {
vec![CommandOutputPolicy::Inherit]
} else if let Some(output_values) = matches.get_many::<String>("output") {
let mut policies = vec![];
for value in output_values {
let policy = match value.as_str() {
"null" => CommandOutputPolicy::Null,
"pipe" => CommandOutputPolicy::Pipe,
"inherit" => CommandOutputPolicy::Inherit,
arg => {
let path = PathBuf::from(arg);
if path.components().count() <= 1 {
return Err(OptionsError::UnknownOutputPolicy(arg.to_string()));
}
CommandOutputPolicy::File(path)
}
CommandOutputPolicy::File(path)
}
};
policies.push(policy);
}
policies
} else {
CommandOutputPolicy::Null
vec![CommandOutputPolicy::Null]
};
options.output_style = match matches.get_one::<String>("style").map(|s| s.as_str()) {
@@ -346,7 +351,10 @@ impl Options {
Some("color") => OutputStyleOption::Color,
Some("none") => OutputStyleOption::Disabled,
_ => {
if options.command_output_policy == CommandOutputPolicy::Inherit
if options
.command_output_policies
.iter()
.any(|policy| *policy == CommandOutputPolicy::Inherit)
|| !io::stdout().is_terminal()
{
OutputStyleOption::Basic
@@ -436,26 +444,34 @@ impl Options {
Ok(options)
}
pub fn validate_against_command_list(&self, commands: &Commands) -> Result<()> {
let num_commands = commands.num_commands()
+ if self.reference_command.is_some() {
1
} else {
0
};
pub fn validate_against_command_list(&mut self, commands: &Commands) -> Result<()> {
let has_reference_command = self.reference_command.is_some();
let num_commands = commands.num_commands(has_reference_command);
if let Some(preparation_command) = &self.preparation_command {
ensure!(
preparation_command.len() <= 1 || num_commands == preparation_command.len(),
"The '--prepare' option has to be provided just once or N times, where N is the \
number of benchmark commands including a potential reference."
"The '--prepare' option has to be provided just once or N times, where N={num_commands} is the \
number of benchmark commands (including a potential reference)."
);
}
if let Some(conclusion_command) = &self.conclusion_command {
ensure!(
conclusion_command.len() <= 1 || num_commands == conclusion_command.len(),
"The '--conclude' option has to be provided just once or N times, where N is the \
number of benchmark commands including a potential reference."
"The '--conclude' option has to be provided just once or N times, where N={num_commands} is the \
number of benchmark commands (including a potential reference)."
);
}
if self.command_output_policies.len() == 1 {
self.command_output_policies =
vec![self.command_output_policies[0].clone(); num_commands];
} else {
ensure!(
self.command_output_policies.len() == num_commands,
"The '--output' option has to be provided just once or N times, where N={num_commands} is the \
number of benchmark commands (including a potential reference)."
);
}
+3 -3
View File
@@ -11,7 +11,7 @@ use nix::fcntl::{splice, SpliceFFlags};
#[cfg(target_os = "linux")]
use std::fs::File;
#[cfg(target_os = "linux")]
use std::os::unix::io::AsRawFd;
use std::os::fd::AsFd;
#[cfg(target_os = "windows")]
use windows_sys::Win32::System::Threading::CREATE_SUSPENDED;
@@ -53,9 +53,9 @@ fn discard(output: ChildStdout) {
{
if let Ok(file) = File::create("/dev/null") {
while let Ok(bytes) = splice(
output.as_raw_fd(),
output.as_fd(),
None,
file.as_raw_fd(),
file.as_fd(),
None,
CHUNK_SIZE,
SpliceFFlags::empty(),
+5 -2
View File
@@ -37,7 +37,7 @@ static NtResumeProcess: Lazy<unsafe extern "system" fn(ProcessHandle: HANDLE) ->
Lazy::new(|| {
// SAFETY: Getting the module handle for ntdll.dll is safe
let ntdll = unsafe { GetModuleHandleW(w!("ntdll.dll")) };
assert!(ntdll != 0, "GetModuleHandleW failed");
assert!(ntdll != std::ptr::null_mut(), "GetModuleHandleW failed");
// SAFETY: The ntdll handle is valid
let nt_resume_process = unsafe { GetProcAddress(ntdll, s!("NtResumeProcess")) };
@@ -56,7 +56,10 @@ impl CPUTimer {
// SAFETY: Creating a new job object is safe
let job_object = unsafe { CreateJobObjectW(ptr::null_mut(), ptr::null_mut()) };
assert!(job_object != 0, "CreateJobObjectW failed");
assert!(
job_object != std::ptr::null_mut(),
"CreateJobObjectW failed"
);
// SAFETY: The job object handle is valid
let ret = unsafe { AssignProcessToJobObject(job_object, child_handle) };