diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml new file mode 100644 index 0000000..2adadd5 --- /dev/null +++ b/.github/workflows/benchmarks.yml @@ -0,0 +1,63 @@ +name: Benchmarks + +# spell-checker:ignore codspeed dtolnay Swatinem sccache + +on: + pull_request: + push: + branches: + - '*' + +permissions: + contents: read # to fetch code (actions/checkout) + +# End the current execution if there is a new changeset in the PR. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + benchmarks: + name: Run benchmarks (CodSpeed) + runs-on: ubuntu-latest + strategy: + matrix: + benchmark-target: + - { package: sed } + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Install system dependencies + shell: bash + run: | + sudo apt-get -y update + + - uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.9 + + - name: Install cargo-codspeed + shell: bash + run: cargo install cargo-codspeed --locked + + - name: Build benchmarks for ${{ matrix.benchmark-target.package }} + shell: bash + run: | + echo "Building benchmarks for ${{ matrix.benchmark-target.package }}" + cargo codspeed build -p ${{ matrix.benchmark-target.package }} + + - name: Run benchmarks for ${{ matrix.benchmark-target.package }} + uses: CodSpeedHQ/action@v4 + env: + CODSPEED_LOG: debug + with: + mode: simulation + run: | + echo "Running benchmarks for ${{ matrix.benchmark-target.package }}" + cargo codspeed run -p ${{ matrix.benchmark-target.package }} > /dev/null + token: ${{ secrets.CODSPEED_TOKEN }} diff --git a/Cargo.toml b/Cargo.toml index 73b1c81..6db2880 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,6 +106,10 @@ name = "uudoc" path = "src/bin/uudoc.rs" required-features = ["uudoc"] +[[bench]] +name = "sed_bench" +harness = false + # The default release profile. It contains all optimizations, without # sacrificing debug info. With this profile (like in the standard # release profile), the debug info and the stack traces will still be available. diff --git a/benches/sed_bench.rs b/benches/sed_bench.rs index 5ff4207..58ac7bc 100644 --- a/benches/sed_bench.rs +++ b/benches/sed_bench.rs @@ -16,7 +16,7 @@ use uucore::benchmark::{create_test_file, run_util_function}; fn no_op_short(bencher: Bencher) { let temp_dir = tempfile::tempdir().unwrap(); let mut data = Vec::new(); - for i in 0..50_000_000 { + for i in 0..10_000_000 { data.extend_from_slice(format!("{}\n", i).as_bytes()); } let file_path = create_test_file(&data, temp_dir.path()); @@ -53,7 +53,7 @@ fn access_log_no_op(bencher: Bencher) { fn access_log_no_subst(bencher: Bencher) { let temp_dir = tempfile::tempdir().unwrap(); let mut data = Vec::new(); - for i in 0..5_000_000 { + for i in 0..1_000_000 { let line = format!( "192.168.{}.{} - - [01/Jan/2024:00:00:00 +0000] \"GET /index.html HTTP/1.1\" 200 1234 \"-\" \"Mozilla/5.0\"\n", (i / 256) % 256, @@ -77,7 +77,7 @@ fn access_log_no_subst(bencher: Bencher) { fn access_log_subst(bencher: Bencher) { let temp_dir = tempfile::tempdir().unwrap(); let mut data = Vec::new(); - for i in 0..5_000_000 { + for i in 0..1_000_000 { let line = format!( "192.168.{}.{} - - [01/Jan/2024:00:00:00 +0000] \"GET /index.html HTTP/1.1\" 200 1234 \"-\" \"Mozilla/5.0\"\n", (i / 256) % 256, @@ -101,7 +101,7 @@ fn access_log_subst(bencher: Bencher) { fn access_log_no_del(bencher: Bencher) { let temp_dir = tempfile::tempdir().unwrap(); let mut data = Vec::new(); - for i in 0..5_000_000 { + for i in 0..1_000_000 { let line = format!( "192.168.{}.{} - - [01/Jan/2024:00:00:00 +0000] \"GET /index.html HTTP/1.1\" 200 1234 \"-\" \"Mozilla/5.0\"\n", (i / 256) % 256, @@ -122,7 +122,7 @@ fn access_log_no_del(bencher: Bencher) { fn access_log_all_del(bencher: Bencher) { let temp_dir = tempfile::tempdir().unwrap(); let mut data = Vec::new(); - for i in 0..5_000_000 { + for i in 0..1_000_000 { let line = format!( "192.168.{}.{} - - [01/Jan/2024:00:00:00 +0000] \"GET /index.html HTTP/1.1\" 200 1234 \"-\" \"Mozilla/5.0\"\n", (i / 256) % 256, @@ -143,7 +143,7 @@ fn access_log_all_del(bencher: Bencher) { fn access_log_translit(bencher: Bencher) { let temp_dir = tempfile::tempdir().unwrap(); let mut data = Vec::new(); - for i in 0..50_000 { + for i in 0..500_000 { let line = format!( "192.168.{}.{} - - [01/Jan/2024:00:00:00 +0000] \"GET /index.html HTTP/1.1\" 200 1234 \"-\" \"Mozilla/5.0\"\n", (i / 256) % 256, @@ -167,7 +167,7 @@ fn access_log_translit(bencher: Bencher) { fn access_log_append(bencher: Bencher) { let temp_dir = tempfile::tempdir().unwrap(); let mut data = Vec::new(); - for i in 0..50_000 { + for i in 0..2_000_000 { let line = format!( "192.168.{}.{} - - [01/Jan/2024:00:00:00 +0000] \"GET /index.html HTTP/1.1\" 200 1234 \"-\" \"Mozilla/5.0\"\n", (i / 256) % 256, @@ -191,7 +191,7 @@ fn access_log_append(bencher: Bencher) { fn remove_cr(bencher: Bencher) { let temp_dir = tempfile::tempdir().unwrap(); let mut data = Vec::new(); - for i in 0..1_500_000 { + for i in 0..500_000 { let line = format!("line {} with windows endings\r\n", i); data.extend_from_slice(line.as_bytes()); } @@ -208,7 +208,7 @@ fn remove_cr(bencher: Bencher) { fn genome_subst(bencher: Bencher) { let temp_dir = tempfile::tempdir().unwrap(); let mut data = Vec::new(); - for i in 0..1_000_000 { + for i in 0..100_000 { let chr = format!("chr{}", 1 + i % 22); let line = format!( "{}\t{}\t{}\t.\t{}\t.\t.\n", @@ -235,7 +235,7 @@ fn genome_subst(bencher: Bencher) { fn number_fix(bencher: Bencher) { let temp_dir = tempfile::tempdir().unwrap(); let mut data = Vec::new(); - for i in 0..700_000 { + for i in 0..100_000 { let euros = i % 10000; let cents = i % 100; let thousands = euros / 1000;