From 76eea583b43d47110d76c637a6f744cfe9eb8993 Mon Sep 17 00:00:00 2001 From: Ben Schofield Date: Mon, 21 Aug 2023 12:10:31 -0700 Subject: [PATCH 1/5] Add benchmarking for `rm` Add benchmarking script and guide for `rm`, mostly copied from `ls` benchmarking guide. Tested `rm` using `jwalk` instead of `walkdir`, and saw a slight performance regression, if any change. --- src/uu/rm/BENCHMARKING.md | 52 +++++++++++++++++++++++++++++++++++++++ src/uu/rm/benchmark.sh | 8 ++++++ 2 files changed, 60 insertions(+) create mode 100644 src/uu/rm/BENCHMARKING.md create mode 100755 src/uu/rm/benchmark.sh diff --git a/src/uu/rm/BENCHMARKING.md b/src/uu/rm/BENCHMARKING.md new file mode 100644 index 00000000000..ee524cb243b --- /dev/null +++ b/src/uu/rm/BENCHMARKING.md @@ -0,0 +1,52 @@ +# 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` + +## Cargo Flamegraph + +With Cargo Flamegraph you can easily make a flamegraph of `rm`: + +```shell +cargo flamegraph --cmd coreutils -- rm [additional parameters] +``` + +However, if the `-r` option is given, the output becomes pretty much useless due to recursion. We can fix this by merging all the direct recursive calls with `uniq`, below is a `bash` script that does this. + +```shell +#!/bin/bash +cargo build --release --no-default-features --features rm +perf record target/release/coreutils rm "$@" +perf script | uniq | inferno-collapse-perf | inferno-flamegraph > flamegraph.svg +``` + diff --git a/src/uu/rm/benchmark.sh b/src/uu/rm/benchmark.sh new file mode 100755 index 00000000000..5feaea4e8f1 --- /dev/null +++ b/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" From 181261beefe8b709d8081b49f98fa5fd8efdc24c Mon Sep 17 00:00:00 2001 From: Ben Schofield Date: Tue, 22 Aug 2023 07:56:24 -0700 Subject: [PATCH 2/5] Add samply to sampling options Add samply to the sampling options for `rm` benchmarking. --- src/uu/rm/BENCHMARKING.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/uu/rm/BENCHMARKING.md b/src/uu/rm/BENCHMARKING.md index ee524cb243b..4170e2df11a 100644 --- a/src/uu/rm/BENCHMARKING.md +++ b/src/uu/rm/BENCHMARKING.md @@ -33,20 +33,28 @@ hyperfine --prepare "cp -r $test_dir tmp_d" "rm -rf tmp_d" "target/release/core - 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` -## Cargo Flamegraph +## Flamegraphs -With Cargo Flamegraph you can easily make a flamegraph of `rm`: +### Samply -```shell -cargo flamegraph --cmd coreutils -- rm [additional parameters] +Samply is one option for simply creating flamegraphs. It isues the Firefox profiler as a UI. + +To install: +```bash +cargo install samply ``` -However, if the `-r` option is given, the output becomes pretty much useless due to recursion. We can fix this by merging all the direct recursive calls with `uniq`, below is a `bash` script that does this. +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 -#!/bin/bash -cargo build --release --no-default-features --features rm -perf record target/release/coreutils rm "$@" -perf script | uniq | inferno-collapse-perf | inferno-flamegraph > flamegraph.svg +cargo flamegraph --cmd coreutils -- rm [additional parameters] ``` From 9ddf218ed97747a9bfd16179b7665f43d79882b1 Mon Sep 17 00:00:00 2001 From: Ben Schofield Date: Tue, 22 Aug 2023 07:59:11 -0700 Subject: [PATCH 3/5] Add samply url --- src/uu/rm/BENCHMARKING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/rm/BENCHMARKING.md b/src/uu/rm/BENCHMARKING.md index 4170e2df11a..a71b3faeda0 100644 --- a/src/uu/rm/BENCHMARKING.md +++ b/src/uu/rm/BENCHMARKING.md @@ -35,9 +35,9 @@ hyperfine --prepare "cp -r $test_dir tmp_d" "rm -rf tmp_d" "target/release/core ## Flamegraphs -### Samply +### samply -Samply is one option for simply creating flamegraphs. It isues the Firefox profiler as a UI. +[samply](https://github.com/mstange/samply) is one option for simply creating flamegraphs. It isues the Firefox profiler as a UI. To install: ```bash From 903490a9c8c505203a6cd80949398e261d03a1ed Mon Sep 17 00:00:00 2001 From: Ben Schofield Date: Wed, 23 Aug 2023 13:05:06 -0700 Subject: [PATCH 4/5] spelling --- src/uu/rm/BENCHMARKING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/rm/BENCHMARKING.md b/src/uu/rm/BENCHMARKING.md index a71b3faeda0..cff93ec9302 100644 --- a/src/uu/rm/BENCHMARKING.md +++ b/src/uu/rm/BENCHMARKING.md @@ -33,11 +33,11 @@ hyperfine --prepare "cp -r $test_dir tmp_d" "rm -rf tmp_d" "target/release/core - 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` -## Flamegraphs +## Flamegraph ### samply -[samply](https://github.com/mstange/samply) is one option for simply creating flamegraphs. It isues the Firefox profiler as a UI. +[samply](https://github.com/mstange/samply) is one option for simply creating flamegraphs. It uses the Firefox profiler as a UI. To install: ```bash From 4d78ca47b11767a6d80c5392ffb3ad8144392aab Mon Sep 17 00:00:00 2001 From: Ben Schofield Date: Thu, 24 Aug 2023 11:15:03 -0600 Subject: [PATCH 5/5] Add Spell ignore Add `samply` and `flamegraph` to spell ignore lists. --- .vscode/cspell.dictionaries/shell.wordlist.txt | 3 +++ src/uu/rm/BENCHMARKING.md | 1 + 2 files changed, 4 insertions(+) diff --git a/.vscode/cspell.dictionaries/shell.wordlist.txt b/.vscode/cspell.dictionaries/shell.wordlist.txt index 16d7b25e997..95dea94a7cd 100644 --- a/.vscode/cspell.dictionaries/shell.wordlist.txt +++ b/.vscode/cspell.dictionaries/shell.wordlist.txt @@ -83,6 +83,8 @@ codespell commitlint dprint dtrace +flamegraph +flamegraphs gcov gmake grcov @@ -90,6 +92,7 @@ grep markdownlint rerast rollup +samply sed selinuxenabled sestatus diff --git a/src/uu/rm/BENCHMARKING.md b/src/uu/rm/BENCHMARKING.md index cff93ec9302..507906d497e 100644 --- a/src/uu/rm/BENCHMARKING.md +++ b/src/uu/rm/BENCHMARKING.md @@ -1,3 +1,4 @@ + # Benchmarking rm Run `cargo build --release` before benchmarking after you make a change!