Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add benchmarking for rm #5187

Merged
merged 5 commits into from Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/cspell.dictionaries/shell.wordlist.txt
Expand Up @@ -83,13 +83,16 @@ codespell
commitlint
dprint
dtrace
flamegraph
flamegraphs
gcov
gmake
grcov
grep
markdownlint
rerast
rollup
samply
sed
selinuxenabled
sestatus
Expand Down
61 changes: 61 additions & 0 deletions src/uu/rm/BENCHMARKING.md
@@ -0,0 +1,61 @@
<!-- spell-checker:ignore samply flamegraph flamegraphs -->
# Benchmarking rm

Run `cargo build --release` before benchmarking after you make a change!

## Simple recursive rm

- Get a large tree, for example linux kernel source tree.
- We'll need to pass a `--prepare` argument, since `rm` deletes the dir each time.
- Benchmark simple recursive rm with hyperfine: `hyperfine --prepare "cp -r tree tree-tmp" "target/release/coreutils rm -r tree-tmp"`.

## Comparing with GNU rm

Hyperfine accepts multiple commands to run and will compare them. To compare performance with GNU rm
duplicate the string you passed to hyperfine but remove the `target/release/coreutils` bit from it.

Example: `hyperfine --prepare "cp -r tree tree-tmp" "target/release/coreutils rm -rf tree-tmp"` becomes
`hyperfine --prepare "cp -r tree tree-tmp" "target/release/coreutils rm -rf tree-tmp" "rm -rf tree-tmp"`
(This assumes GNU rm is installed as `rm`)

This can also be used to compare with version of rm built before your changes to ensure your change does not regress this.

Here is a `bash` script for doing this comparison:

```shell
#!/bin/bash
cargo build --no-default-features --features rm --release
test_dir="$1"
hyperfine --prepare "cp -r $test_dir tmp_d" "rm -rf tmp_d" "target/release/coreutils rm -rf tmp_d"
```

## Checking system call count

- Another thing to look at would be system calls count using strace (on linux) or equivalent on other operating systems.
- Example: `strace -c target/release/coreutils rm -rf tree`

## Flamegraph

### samply

[samply](https://github.com/mstange/samply) is one option for simply creating flamegraphs. It uses the Firefox profiler as a UI.

To install:
```bash
cargo install samply
```

To run:

```bash
samply record target/release/coreutils rm -rf ../linux
```

### Cargo Flamegraph

With Cargo Flamegraph you can easily make a flamegraph of `rm`:

```shell
cargo flamegraph --cmd coreutils -- rm [additional parameters]
```

8 changes: 8 additions & 0 deletions src/uu/rm/benchmark.sh
@@ -0,0 +1,8 @@
#!/bin/bash

# Exit on any failures
set +x

cargo build --no-default-features --features rm --release
test_dir="$1"
hyperfine --prepare "cp -r $test_dir tmp_d" "rm -rf tmp_d" "target/release/coreutils rm -rf tmp_d"