mirror of
https://github.com/sharkdp/hyperfine.git
synced 2026-11-14 16:31:31 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29ec4accd1 | ||
|
|
7395dde05d | ||
|
|
e262cd6ea5 |
No files matched your search
+44
-2
@@ -2,8 +2,50 @@
|
||||
|
||||
## Breaking changes
|
||||
|
||||
- Execute commands directly by default (`--shell=none`). Use `-S` (an alias for `--shell=default`) to restore the previous behavior (`sh` on Unix, `cmd.exe` on Windows), or select a shell with `--shell <SHELL>`.
|
||||
- Repurpose `-S` as an alias for `--shell=default`. It no longer accepts a shell argument; replace `-S <SHELL>` with `--shell <SHELL>`.
|
||||
- Benchmarked commands are now always executed directly, without an intermediate shell (`--shell=none`). Use `-S` (an alias for `--shell=default`) to restore the previous behavior (`sh` on Unix, `cmd.exe` on Windows), or select a shell with `--shell <SHELL>`.
|
||||
- The JSON format for `--export-json` has changed (schema version 2). The new format now includes metadata, per-run measurements, and statistical summaries for all measured quantities, see #790 (@sharkdp). Code that reads those exported JSON files must be updated. For example, `results[i].mean` is now `results[i].summary.time_wall_clock.mean`, and `results[i].times` is replaced by `results[i].measurements[j].time_wall_clock.value`. The new structure looks like this:
|
||||
|
||||
```python
|
||||
{
|
||||
"schema_version": 2,
|
||||
"metadata": {
|
||||
"hyperfine_version": "1.21.0",
|
||||
"start_time": "2026-10-06T12:00:00Z",
|
||||
"platform": {"os": "Linux", "architecture": "x86_64"}
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"command": "sleep 1", # Actual command after parameter substitution
|
||||
"name": "wait 1s", # Optional custom name, separate from the command
|
||||
"parameters": {"duration": {"value": "1"}}, # Values are now objects
|
||||
"measurements": [ # One entry per run, excluding warmups
|
||||
{
|
||||
"time_wall_clock": {"value": 1.0, "unit": "second"},
|
||||
"time_user": {"value": 0.0, "unit": "second"},
|
||||
"time_system": {"value": 0.0, "unit": "second"},
|
||||
"memory_peak_resident": {"value": 1048576.0, "unit": "byte"},
|
||||
"exit_code": 0
|
||||
},
|
||||
... # Further runs omitted
|
||||
],
|
||||
"summary": {
|
||||
"time_wall_clock": {
|
||||
"unit": "second",
|
||||
"count": 2,
|
||||
"mean": 1.0,
|
||||
"stddev": 0.0,
|
||||
"median": 1.0,
|
||||
"min": 1.0,
|
||||
"max": 1.0
|
||||
}
|
||||
# Other metrics have the same summary structure.
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Times are always exported in seconds and memory in bytes.
|
||||
|
||||
# v1.21.0
|
||||
|
||||
|
||||
@@ -184,7 +184,9 @@ The JSON export includes the following metrics for each measured run (excluding
|
||||
|
||||
- Linux/macOS: Peak resident set size (RSS). This is the largest per-process peak among the
|
||||
command and child processes (whose usage is collected when their parents wait for them),
|
||||
*not the simultaneous total memory of the full process tree*.
|
||||
*not the simultaneous total memory of the full process tree*. On Linux, measuring commands
|
||||
with a very small peak RSS (below the peak inherited from hyperfine at startup, which can
|
||||
be a few MiB) will currently result in that inherited value being reported instead.
|
||||
- Windows: Currently not supported.
|
||||
|
||||
- **`cpu_cycles`**: CPU cycles consumed.
|
||||
|
||||
@@ -7,6 +7,14 @@ hyperfine 'sleep 0.020' 'sleep 0.021' 'sleep 0.022' --export-json sleep.json
|
||||
uv run plot_whisker.py sleep.json
|
||||
```
|
||||
|
||||
All plotting scripts accept `--metric` to select a metric. Hardware counters
|
||||
(`cpu_cycles`, `instructions`, `cache_references`, `cache_misses`, and `branch_misses`)
|
||||
are plotted as unscaled counts when available in the JSON export. For example:
|
||||
|
||||
```bash
|
||||
uv run plot_histogram.py benchmark.json --metric instructions
|
||||
```
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Install [`uv`](https://docs.astral.sh/uv/getting-started/installation/) and run the
|
||||
|
||||
@@ -54,14 +54,14 @@ parser.add_argument(
|
||||
"--t-min",
|
||||
dest="value_min",
|
||||
type=float,
|
||||
help="Minimum value to display (seconds, or MiB for memory)",
|
||||
help="Minimum metric value to display",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--max",
|
||||
"--t-max",
|
||||
dest="value_max",
|
||||
type=float,
|
||||
help="Maximum value to display (seconds, or MiB for memory)",
|
||||
help="Maximum metric value to display",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--log-count",
|
||||
|
||||
@@ -5,6 +5,11 @@ METRICS = {
|
||||
"time_user": ("User CPU time [s]", 1),
|
||||
"time_system": ("System CPU time [s]", 1),
|
||||
"memory_peak_resident": ("Peak resident memory [MiB]", 1024**2),
|
||||
"cpu_cycles": ("CPU cycles", 1),
|
||||
"instructions": ("Completed CPU instructions", 1),
|
||||
"cache_references": ("Cache references", 1),
|
||||
"cache_misses": ("Cache misses", 1),
|
||||
"branch_misses": ("Mispredicted branches", 1),
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +19,7 @@ def add_metric_argument(parser):
|
||||
choices=METRICS,
|
||||
default="time_wall_clock",
|
||||
help="Metric to plot (default: time_wall_clock). "
|
||||
"Times are in seconds; memory is in MiB.",
|
||||
"Times are in seconds; memory is in MiB; hardware counters are unscaled counts.",
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user