From 7abdfd3f3e48a42e94ff93c0c1dd82c0d5190cb3 Mon Sep 17 00:00:00 2001 From: Leander Date: Fri, 31 Oct 2025 20:28:01 +0100 Subject: [PATCH 1/2] ci: add tango for interleaved benchmarking --- .github/workflows/ci.yml | 20 ++ Cargo.lock | 487 +++++++++++++++++++++++++++++++++++++- Cargo.toml | 5 + benches/byte_set_tango.rs | 217 +++++++++++++++++ build.rs | 4 + 5 files changed, 732 insertions(+), 1 deletion(-) create mode 100644 benches/byte_set_tango.rs create mode 100644 build.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c35643b..61e9201 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,8 +52,28 @@ jobs: - name: Install iai-callgrind-runner run: cargo install --locked --version 0.16.1 iai-callgrind-runner + - name: Install cargo-export + run: cargo install --locked cargo-export + - name: Export runner path run: echo "IAI_CALLGRIND_RUNNER=$(which iai-callgrind-runner)" >> "$GITHUB_ENV" - name: Run benchmarks run: cargo bench --bench byte_set + + - name: Prepare Tango baseline (main) + run: | + git fetch origin main + git worktree add ../tango-baseline origin/main + mkdir -p ../tango-baseline-artifacts + pushd ../tango-baseline + cargo fetch + cargo export ../tango-baseline-artifacts -- bench --bench=byte_set_tango + popd + + - name: Run Tango benchmarks vs main + run: cargo bench -q --bench byte_set_tango -- compare ../tango-baseline-artifacts/byte_set_tango --fail-threshold 1.0 --fail-fast + + - name: Cleanup Tango baseline + if: always() + run: git worktree remove --force ../tango-baseline || true diff --git a/Cargo.lock b/Cargo.lock index 86507eb..bcb71f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,77 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "alloca" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + [[package]] name = "bincode" version = "1.3.3" @@ -11,12 +82,83 @@ dependencies = [ "serde", ] +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "cc" +version = "1.2.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" +dependencies = [ + "find-msvc-tools", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "clap" +version = "4.5.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "colorz" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceb37c5798821e37369cb546f430f19da2f585e0364c9615ae340a9f2e6067b" +dependencies = [ + "supports-color", +] + [[package]] name = "comtains" version = "0.1.1" @@ -24,6 +166,7 @@ dependencies = [ "comtains_macros", "iai-callgrind", "rand", + "tango-bench", ] [[package]] @@ -55,6 +198,28 @@ dependencies = [ "syn", ] +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + [[package]] name = "getrandom" version = "0.2.16" @@ -66,6 +231,41 @@ dependencies = [ "wasi", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "glob-match" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" + +[[package]] +name = "goblin" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27c1b4369c2cd341b5de549380158b105a04c331be5db9110eef7b6d2742134" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "iai-callgrind" version = "0.16.1" @@ -102,6 +302,18 @@ dependencies = [ "serde", ] +[[package]] +name = "is_ci" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + [[package]] name = "itoa" version = "1.0.15" @@ -114,12 +326,61 @@ version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + [[package]] name = "memchr" version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -169,6 +430,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rand" version = "0.8.5" @@ -196,7 +463,20 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.16", +] + +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", ] [[package]] @@ -205,6 +485,26 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde" version = "1.0.228" @@ -248,6 +548,27 @@ dependencies = [ "serde_core", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "supports-color" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" +dependencies = [ + "is_ci", +] + [[package]] name = "syn" version = "2.0.107" @@ -259,18 +580,182 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tango-bench" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257822358c6f206fed78bfe6369cf959063b0644d70f88df6b19f2dadc93423e" +dependencies = [ + "alloca", + "anyhow", + "clap", + "colorz", + "glob-match", + "goblin", + "libloading", + "log", + "num-traits", + "rand", + "scroll", + "tempfile", + "thiserror", +] + +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-ident" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + [[package]] name = "zerocopy" version = "0.8.27" diff --git a/Cargo.toml b/Cargo.toml index de9377f..a295b0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,12 @@ comtains_macros = { path = "comtains_macros", version = "0.1.0" } [dev-dependencies] iai-callgrind = "0.16" rand = { version = "0.8", default-features = false, features = ["std", "std_rng"] } +tango-bench = "0.6" [[bench]] name = "byte_set" harness = false + +[[bench]] +name = "byte_set_tango" +harness = false diff --git a/benches/byte_set_tango.rs b/benches/byte_set_tango.rs new file mode 100644 index 0000000..c57b4de --- /dev/null +++ b/benches/byte_set_tango.rs @@ -0,0 +1,217 @@ +use std::hint::black_box; + +use comtains::{ByteSet, byte_set}; +use rand::{Rng, SeedableRng, rngs::StdRng}; +use tango_bench::{IntoBenchmarks, benchmark_fn, tango_benchmarks, tango_main}; + +const HOT_SET: ByteSet = byte_set![b"\xA0\xB1", b"\xA1\xB2", b"\xA1\xB2\xC3", b"\xA1\xB2\xC4",]; + +const HOT_SEQUENCES: [&[u8]; 4] = [b"\xA0\xB1", b"\xA1\xB2", b"\xA1\xB2\xC3", b"\xA1\xB2\xC4"]; + +const LARGE_SET: ByteSet = byte_set![ + b"\x10\x00", + b"\x10\x01", + b"\x10\x02", + b"\x10\x03", + b"\x10\x04", + b"\x10\x05", + b"\x10\x06", + b"\x10\x07", + b"\x10\x08", + b"\x10\x09", + b"\x10\x0A", + b"\x10\x0B", + b"\x10\x0C", + b"\x10\x0D", + b"\x10\x0E", + b"\x10\x0F", + b"\x20\x00", + b"\x20\x01", + b"\x20\x02", + b"\x20\x03", + b"\x20\x04", + b"\x20\x05", + b"\x20\x06", + b"\x20\x07", + b"\x20\x08", + b"\x20\x09", + b"\x20\x0A", + b"\x20\x0B", + b"\x20\x0C", + b"\x20\x0D", + b"\x20\x0E", + b"\x20\x0F", + b"\x30\x00\xFF", + b"\x30\x01\xFE", + b"\x30\x02\xFD", + b"\x30\x03\xFC", + b"\x40\x00\xFF\xE0", + b"\x40\x01\xFE\xE1", + b"\x40\x02\xFD\xE2", + b"\x40\x03\xFC\xE3", +]; + +const LARGE_SEQUENCES: [&[u8]; 40] = [ + b"\x10\x00", + b"\x10\x01", + b"\x10\x02", + b"\x10\x03", + b"\x10\x04", + b"\x10\x05", + b"\x10\x06", + b"\x10\x07", + b"\x10\x08", + b"\x10\x09", + b"\x10\x0A", + b"\x10\x0B", + b"\x10\x0C", + b"\x10\x0D", + b"\x10\x0E", + b"\x10\x0F", + b"\x20\x00", + b"\x20\x01", + b"\x20\x02", + b"\x20\x03", + b"\x20\x04", + b"\x20\x05", + b"\x20\x06", + b"\x20\x07", + b"\x20\x08", + b"\x20\x09", + b"\x20\x0A", + b"\x20\x0B", + b"\x20\x0C", + b"\x20\x0D", + b"\x20\x0E", + b"\x20\x0F", + b"\x30\x00\xFF", + b"\x30\x01\xFE", + b"\x30\x02\xFD", + b"\x30\x03\xFC", + b"\x40\x00\xFF\xE0", + b"\x40\x01\xFE\xE1", + b"\x40\x02\xFD\xE2", + b"\x40\x03\xFC\xE3", +]; + +const MISS_SEQUENCES: [&[u8]; 8] = [ + b"", + b"\xFF", + b"\xA1", + b"\xA1\xB3", + b"\xA1\xB2\x00", + b"\xA1\xB2\xC5", + b"\xA0\xB1\x01", + b"\xFF\xFF\xFF\xFF", +]; + +const MIXED_WORKLOAD: [&[u8]; 12] = [ + b"\xA1\xB2", + b"\xA1\xB2\xC3", + b"\xA1\xB2\xC5", + b"\xA0\xB1", + b"\xA2\xB0", + b"\xA1\xB3", + b"\xA1\xB2\xC4", + b"\xA1\xB2\x00", + b"\x00", + b"\xA1", + b"\xA1\xB2\xC3\xD0", + b"", +]; + +fn naive_contains(set: &[&[u8]], candidate: &[u8]) -> bool { + for seq in set { + if *seq == candidate { + return true; + } + } + false +} + +fn byte_set_benchmarks() -> impl IntoBenchmarks { + [ + benchmark_fn("byte_set_hot_hit", |b| { + b.iter(|| black_box(HOT_SET.contains(black_box(b"\xA1\xB2")))) + }), + benchmark_fn("byte_set_cold_hit", |b| { + b.iter(|| black_box(HOT_SET.contains(black_box(b"\xA0\xB1")))) + }), + benchmark_fn("byte_set_short_miss", |b| { + b.iter(|| black_box(HOT_SET.contains(black_box(b"\xFF")))) + }), + benchmark_fn("byte_set_long_miss", |b| { + b.iter(|| black_box(HOT_SET.contains(black_box(b"\xA1\xB2\xFF")))) + }), + benchmark_fn("byte_set_mixed_workload", |b| { + b.iter(|| { + let mut hits = 0usize; + for candidate in MIXED_WORKLOAD { + if HOT_SET.contains(black_box(candidate)) { + hits += 1; + } + } + black_box(hits) + }) + }), + benchmark_fn("naive_mixed_workload", |b| { + b.iter(|| { + let mut hits = 0usize; + for candidate in MIXED_WORKLOAD { + if naive_contains(black_box(&HOT_SEQUENCES), black_box(candidate)) { + hits += 1; + } + } + black_box(hits) + }) + }), + benchmark_fn("byte_set_large_dense_hits", |b| { + b.iter(|| { + let mut hits = 0usize; + for candidate in LARGE_SEQUENCES { + if LARGE_SET.contains(black_box(candidate)) { + hits += 1; + } + } + black_box(hits) + }) + }), + benchmark_fn("naive_large_dense_hits", |b| { + b.iter(|| { + let mut hits = 0usize; + for candidate in LARGE_SEQUENCES { + if naive_contains(black_box(&LARGE_SEQUENCES), black_box(candidate)) { + hits += 1; + } + } + black_box(hits) + }) + }), + benchmark_fn("byte_set_large_pathological_miss", |b| { + b.iter(|| black_box(LARGE_SET.contains(black_box(b"\xFF\xFF\xFF\xFF")))) + }), + benchmark_fn("byte_set_randomized_mix", |b| { + let seed = b.seed; + b.iter(move || { + let mut rng = StdRng::seed_from_u64(seed ^ 0xBADC0FFE); + let mut hits = 0usize; + let hit_len = HOT_SEQUENCES.len(); + let miss_len = MISS_SEQUENCES.len(); + for _ in 0..512 { + let candidate = if rng.gen_bool(0.7) { + HOT_SEQUENCES[rng.gen_range(0..hit_len)] + } else { + MISS_SEQUENCES[rng.gen_range(0..miss_len)] + }; + if HOT_SET.contains(black_box(candidate)) { + hits += 1; + } + } + black_box(hits) + }) + }), + ] +} + +tango_benchmarks!(byte_set_benchmarks()); +tango_main!(); diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..0decd5d --- /dev/null +++ b/build.rs @@ -0,0 +1,4 @@ +fn main() { + println!("cargo:rustc-link-arg-benches=-rdynamic"); + println!("cargo:rerun-if-changed=build.rs"); +} From 970944f70dbb1951bded0982499dfcf99f6c220e Mon Sep 17 00:00:00 2001 From: Leander Date: Fri, 31 Oct 2025 20:32:13 +0100 Subject: [PATCH 2/2] ci: add missing tango bench target --- .github/workflows/ci.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61e9201..7559478 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,12 +67,22 @@ jobs: git worktree add ../tango-baseline origin/main mkdir -p ../tango-baseline-artifacts pushd ../tango-baseline - cargo fetch - cargo export ../tango-baseline-artifacts -- bench --bench=byte_set_tango + if cargo bench --bench byte_set_tango --no-run >/dev/null 2>&1; then + cargo export ../tango-baseline-artifacts -- bench --bench=byte_set_tango + echo "TANGO_BASELINE_READY=1" >> "$GITHUB_ENV" + else + echo "Tango bench target missing on baseline; skipping compare." + echo "TANGO_BASELINE_READY=0" >> "$GITHUB_ENV" + fi popd - name: Run Tango benchmarks vs main - run: cargo bench -q --bench byte_set_tango -- compare ../tango-baseline-artifacts/byte_set_tango --fail-threshold 1.0 --fail-fast + run: | + if [ "${TANGO_BASELINE_READY:-0}" != "1" ]; then + echo "Skipping Tango compare; baseline missing bench target." + exit 0 + fi + cargo bench -q --bench byte_set_tango -- compare ../tango-baseline-artifacts/byte_set_tango --fail-threshold 1.0 --fail-fast - name: Cleanup Tango baseline if: always()