Skip to content

Commit b904a5c

Browse files
authored
Merge pull request #1674 from Kobzol/runtime-doc
Add more runtime benchmark documentation
2 parents 33d2d1e + 9e5e3e6 commit b904a5c

File tree

2 files changed

+84
-2
lines changed

2 files changed

+84
-2
lines changed

collector/README.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ Hardware and software details of the machine that executes the CI details can be
66

77
## The benchmarks
88

9-
The individual compile time benchmarks are described in the `README` file in the
9+
Compile time benchmarks are described in the `README` file in the
1010
`collector/compile-benchmarks` directory.
1111

12+
Runtime benchmarks are described in the `README` file in the
13+
`collector/runtime-benchmarks` directory.
14+
1215
## How to build
1316

1417
Before doing anything else, you should build `collector` (for running the
@@ -65,7 +68,8 @@ marked with a '?' in the `compare` page.
6568

6669
### How to benchmark a change on your own machine
6770

68-
The following command runs the benchmark suite using a local rustc:
71+
The following command runs the compile benchmark suite (which measures how long does it take to compile
72+
various crates with rustc) using a local rustc:
6973
```
7074
./target/release/collector bench_local <RUSTC>
7175
```
@@ -167,6 +171,22 @@ something like this:
167171
where `$RUST_ORIGINAL` and `$RUST_MODIFIED` are paths (relative or absolute) to
168172
the relevant rustc executables.
169173

174+
#### Runtime benchmarks
175+
There is also a runtime benchmark suite, which measures the performance of Rust programs compiled
176+
by a selected version of rustc. You can run it using the following command:
177+
```bash
178+
./target/release/collector bench_runtime_local <RUSTC>
179+
```
180+
181+
### Benchmarking options
182+
183+
The following options alter the behaviour of the `bench_runtime_local` subcommand.
184+
- `--no-isolate`: you can use this flag to make repeated local benchmarks faster. It will cause the
185+
`collector` to reuse compiled artifacts of the runtime benchmark groups.
186+
187+
The `bench_runtime_local` command also shares some options with the `bench_local` command, notably
188+
`--id`, `--db`, `--cargo`, `--include`, `--exclude` and `--iterations`.
189+
170190
### How to view the measurements on your own machine
171191

172192
Once the benchmarks have been run, build and start the website.

collector/runtime-benchmarks/README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,68 @@ Runtime benchmarks are divided into groups so that some benchmarks can use diffe
1111
dependency crates and also so that they are grouped together by a relevant area
1212
(e.g. hashmap benchmarks).
1313

14+
## Benchmark descriptions
15+
> The runtime benchmark suite is currently experimental, so it is possible that some benchmarks will
16+
be heavily modified or removed, and new ones will be added. Once the suite will be more stable, the
17+
individual benchmarks will be described here.
18+
19+
## How to add a new benchmark
20+
First you should decide whether you will create a new benchmark group or not. If you find a group that
21+
seems relevant to your benchmark (e.g. if you want to add a new benchmark that tests the performance
22+
of a hash map, the `hashmap` group is ideal for that), then
23+
[add the benchmark](#adding-a-benchmark-to-a-benchmark-group) to it directly. If not, you should create
24+
a new group.
25+
26+
### Creating a new benchmark group
27+
You can create a new benchmark group either by copying an existing group or by creating a new binary
28+
crate in this directory and adding a dependency on the [`benchlib`](../benchlib) crate to it.
29+
30+
By convention, if a group (its directory) is called `foo`, then the crate name should be `foo-bench`.
31+
This convention exists to enable creation of groups that have the same name as a dependency that they
32+
benchmark.
33+
34+
Each group should call the `run_benchmark_group` function from `benchlib` in its `main` function, and
35+
define a set of benchmarks inside a closure passed to the function. This is an example of how that could
36+
look like:
37+
38+
```rust
39+
use benchlib::benchmark::run_benchmark_group;
40+
41+
fn main() {
42+
// Initialize the benchmarking infrastructure
43+
run_benchmark_group(|group| {
44+
// Register a benchmark called bench_1
45+
group.register_benchmark("bench_1", || {
46+
// This closure should prepare data that will be needed for the benchmark (if any),
47+
// and then return a closure that will actually be benchmarked/profiled.
48+
let data = vec![0; 1024];
49+
move || {
50+
// Only this will be actually benchmarked
51+
data.iter().sum::<u64>()
52+
}
53+
});
54+
});
55+
}
56+
```
57+
58+
### Adding a benchmark to a benchmark group
59+
Once you have selected a benchmark group, add a new benchmark to it by calling `group.register_benchmark(...)`.
60+
See above for the description of this function.
61+
62+
Note that if your benchmark requires only immutable access to some input data, consider creating the
63+
data only once in `main`, and then referencing it in the benchmarked function. This will make the
64+
benchmark run faster if the data preparation is expensive. It could also in theory reduce noise/variance,
65+
because the data will exist on a stable address in memory and won't be (re)allocated before each benchmark
66+
iteration.
67+
68+
> Currently, there is a trade-off to doing a lot of stuff in `main` - it will make the enumeration of
69+
> benchmarks slower, which can be annoying when doing many local benchmarks. See below for more information.
70+
71+
### What benchmarks are we interested in?
72+
It is hard to say in general, but we tend to prefer benchmarks containing real-world code that does
73+
something useful, rather than microbenchmarks. Benchmarks also shouldn't be too short - a benchmark
74+
should take at least tens or hundreds of milliseconds.
75+
1476
## How are benchmarks executed
1577
The `collector` compiles each benchmark group and then invokes it with the `list` argument to list
1678
all benchmarks contained in the group.

0 commit comments

Comments
 (0)