From d011b0142f982a7190a2c285ac3ea8747632219f Mon Sep 17 00:00:00 2001
From: Valentin Trophime <valentin.trophime@inria.fr>
Date: Thu, 7 Nov 2024 00:59:27 +0100
Subject: [PATCH] try criterion + add default repeat in overhead

---
 Cargo.lock              | 560 ++++++++++++++++++++++++++++++++++++++++
 Cargo.toml              |   4 +
 benches/my_benchmark.rs |  73 ++++++
 examples/overhead.rs    |  12 +-
 scripts/heatmap.py      |  62 +++--
 5 files changed, 692 insertions(+), 19 deletions(-)
 create mode 100644 benches/my_benchmark.rs

diff --git a/Cargo.lock b/Cargo.lock
index 56840fb..eeb7f23 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,24 +2,161 @@
 # It is not intended for manual editing.
 version = 3
 
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bumpalo"
+version = "3.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+
 [[package]]
 name = "byteorder"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
+[[package]]
+name = "cast"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
+
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
+[[package]]
+name = "clap"
+version = "2.34.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
+dependencies = [
+ "bitflags",
+ "textwrap",
+ "unicode-width",
+]
+
+[[package]]
+name = "criterion"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f"
+dependencies = [
+ "atty",
+ "cast",
+ "clap",
+ "criterion-plot",
+ "csv",
+ "itertools",
+ "lazy_static",
+ "num-traits",
+ "oorandom",
+ "plotters",
+ "rayon",
+ "regex",
+ "serde",
+ "serde_cbor",
+ "serde_derive",
+ "serde_json",
+ "tinytemplate",
+ "walkdir",
+]
+
+[[package]]
+name = "criterion-plot"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876"
+dependencies = [
+ "cast",
+ "itertools",
+]
+
 [[package]]
 name = "critical-section"
 version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
 
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
+
+[[package]]
+name = "csv"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe"
+dependencies = [
+ "csv-core",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "csv-core"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "darling"
 version = "0.20.10"
@@ -64,6 +201,12 @@ dependencies = [
  "litrs",
 ]
 
+[[package]]
+name = "either"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
+
 [[package]]
 name = "embassy-executor"
 version = "0.6.2"
@@ -213,6 +356,12 @@ dependencies = [
  "pin-utils",
 ]
 
+[[package]]
+name = "half"
+version = "1.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
+
 [[package]]
 name = "hash32"
 version = "0.3.1"
@@ -232,12 +381,57 @@ dependencies = [
  "stable_deref_trait",
 ]
 
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "ident_case"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+
+[[package]]
+name = "js-sys"
+version = "0.3.72"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+
+[[package]]
+name = "libc"
+version = "0.2.161"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
+
 [[package]]
 name = "litrs"
 version = "0.4.1"
@@ -250,6 +444,12 @@ version = "0.4.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
 
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
 [[package]]
 name = "nb"
 version = "0.1.3"
@@ -265,6 +465,27 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
 
+[[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.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+
+[[package]]
+name = "oorandom"
+version = "11.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9"
+
 [[package]]
 name = "pin-project-lite"
 version = "0.2.15"
@@ -277,10 +498,39 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
+[[package]]
+name = "plotters"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747"
+dependencies = [
+ "num-traits",
+ "plotters-backend",
+ "plotters-svg",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "plotters-backend"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a"
+
+[[package]]
+name = "plotters-svg"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670"
+dependencies = [
+ "plotters-backend",
+]
+
 [[package]]
 name = "preemptive-iterator"
 version = "0.1.0"
 dependencies = [
+ "criterion",
  "critical-section",
  "embassy-executor",
  "embassy-futures",
@@ -306,6 +556,55 @@ dependencies = [
  "proc-macro2",
 ]
 
+[[package]]
+name = "rayon"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "regex"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
 [[package]]
 name = "rustc_version"
 version = "0.4.1"
@@ -315,12 +614,69 @@ dependencies = [
  "semver",
 ]
 
+[[package]]
+name = "ryu"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
 [[package]]
 name = "semver"
 version = "1.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
 
+[[package]]
+name = "serde"
+version = "1.0.214"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_cbor"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
+dependencies = [
+ "half",
+ "serde",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.214"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.132"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
+dependencies = [
+ "itoa",
+ "memchr",
+ "ryu",
+ "serde",
+]
+
 [[package]]
 name = "stable_deref_trait"
 version = "1.2.0"
@@ -344,14 +700,218 @@ dependencies = [
  "unicode-ident",
 ]
 
+[[package]]
+name = "textwrap"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+dependencies = [
+ "unicode-width",
+]
+
+[[package]]
+name = "tinytemplate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "unicode-ident"
 version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
 
+[[package]]
+name = "unicode-width"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
+
 [[package]]
 name = "void"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+
+[[package]]
+name = "walkdir"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
+
+[[package]]
+name = "web-sys"
+version = "0.3.72"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "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.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/Cargo.toml b/Cargo.toml
index 5b21751..89ca43d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,11 @@ embassy-futures = "0.1.1"
 embassy-sync = "0.6.0" 
 embassy-executor = { version = "0.6.0", features = ["task-arena-size-32768", "arch-std", "executor-thread", "integrated-timers"] }
 critical-section = { version = "1.1", features = ["std"] }
+criterion = "0.3"
 
+[[bench]]
+name = "my_benchmark"
+harness = false
 
 [profile.release-with-debug]
 inherits = "release"
diff --git a/benches/my_benchmark.rs b/benches/my_benchmark.rs
new file mode 100644
index 0000000..e71cdfe
--- /dev/null
+++ b/benches/my_benchmark.rs
@@ -0,0 +1,73 @@
+use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
+use embassy_futures::block_on;
+use embassy_time::Duration;
+use preemptive_iterator::{AsyncIterator, PreemptiveIterator};
+use std::hint::black_box;
+
+pub fn criterion_benchmark(c: &mut Criterion) {
+    let n_iters = [100];
+    // let n_iters = [100, 1_000, 10_000];
+    let task_dur = 10;
+    let reac = 10;
+    let reac_d = Duration::from_micros(reac);
+    let mut group = c.benchmark_group("Iterator");
+    for n_iter in n_iters {
+        group.bench_function(BenchmarkId::new("Preemptive", n_iter), |b| {
+            b.iter(|| preemptive(n_iter, task_dur, reac_d))
+        });
+        group.bench_function(BenchmarkId::new("Preemptive2", n_iter), |b| {
+            b.iter(|| preemptive2(n_iter, task_dur, reac_d))
+        });
+        group.bench_function(BenchmarkId::new("PreemptiveFixed", n_iter), |b| {
+            b.iter(|| preemptive_fixed(n_iter, task_dur, reac as usize))
+        });
+        group.bench_function(BenchmarkId::new("Baseline", n_iter), |b| {
+            b.iter(|| baseline(n_iter, task_dur))
+        });
+    }
+    group.finish();
+}
+
+criterion_group!(benches, criterion_benchmark);
+criterion_main!(benches);
+
+#[inline(never)]
+pub fn preemptive(n_iter: u32, task_dur: u32, reac: Duration) {
+    black_box(block_on(black_box(0..n_iter).preemptive_for_each(
+        black_box(|_| work(task_dur)),
+        black_box(reac),
+    )))
+}
+#[inline(never)]
+pub fn preemptive2(n_iter: u32, task_dur: u32, reac: Duration) {
+    black_box(block_on(
+        black_box(0..n_iter).async_for_each(black_box(|_| work(task_dur)), black_box(reac)),
+    ))
+}
+#[inline(never)]
+pub fn preemptive_fixed(n_iter: u32, task_dur: u32, reac: usize) {
+    black_box(block_on(
+        black_box(0..n_iter)
+            .preemptive_for_each_fixed_block(black_box(|_| work(task_dur)), black_box(reac)),
+    ))
+}
+#[inline(never)]
+pub fn baseline(n_iter: u32, task_dur: u32) {
+    black_box(block_on(async {
+        black_box(0..n_iter).for_each(black_box(|_| work(task_dur)))
+    }))
+}
+
+#[inline(never)]
+fn work(task_duration: u32) {
+    let mut res = 0.0;
+    let mut i = 0;
+    loop {
+        res += (i as f64) * (i as f64);
+        i += 1;
+        if i == task_duration {
+            break;
+        }
+    }
+    std::hint::black_box(res);
+}
diff --git a/examples/overhead.rs b/examples/overhead.rs
index 83b664f..d9499ef 100644
--- a/examples/overhead.rs
+++ b/examples/overhead.rs
@@ -68,6 +68,7 @@ struct Args {
 }
 
 impl Args {
+    #[inline(never)]
     fn parse() -> Self {
         const N_ARGS: usize = 4;
         const DUR: &'static str = "--duration-task=";
@@ -75,7 +76,7 @@ impl Args {
         const NITER: &'static str = "--n-iter=";
         const REPEAT: &'static str = "--repeat=";
         let args: Vec<String> = std::env::args().collect();
-        if args.len() != N_ARGS + 1 {
+        if args.len() < N_ARGS {
             panic!("Usage: ./exec {DUR}1 {REAC}1 {NITER}1 {REPEAT}1")
         }
         let mut res = Args::default();
@@ -92,18 +93,25 @@ impl Args {
                 panic!("Unknown argument: {arg}")
             }
         }
+        if res.repeat == u32::default() {
+            res.repeat = 2;
+        }
         res
     }
 }
 fn main() {
     let args = Args::parse();
     for _ in 0..args.repeat {
-        let time_ref = time_baseline(0..args.n_iter, |_| work(args.duration_task));
         let [time_auto, time_manual, time_auto2] =
             time_contender(args.n_iter, args.reactivity_us, args.duration_task);
+        let time_ref = time_baseline(0..args.n_iter, |_| work(args.duration_task));
         println!("Baseline: {}", time_ref.as_nanos());
         println!("Preemptive: {}", time_auto.as_nanos());
         println!("PreemptiveFixed: {}", time_manual.as_nanos());
         println!("Preemptive2: {}", time_auto2.as_nanos());
+        // black_box(time_auto);
+        // black_box(time_auto2);
+        // black_box(time_ref);
+        // black_box(time_manual);
     }
 }
diff --git a/scripts/heatmap.py b/scripts/heatmap.py
index dceaa97..949026c 100755
--- a/scripts/heatmap.py
+++ b/scripts/heatmap.py
@@ -1,4 +1,5 @@
 #! /usr/bin/env python3
+# PYTHON_ARGCOMPLETE_OK
 
 import argparse
 from io import TextIOWrapper
@@ -77,9 +78,14 @@ class CollectorCSV:
             else:
                 print("Do nothing")
                 return
+        env = os.environ
+        env["RUSTFLAGS"] = (
+            "-C llvm-args=-align-all-functions=6 -C llvm-args=-align-all-nofallthru-blocks=6"
+        )
         subprocess.run(
             ["cargo", "build", "--profile", self.profile, "--example", "overhead"],
             check=True,
+            env=env,
         )
         with open("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "r") as f:
             if f.read().strip() != "performance":
@@ -143,12 +149,28 @@ def get_overhead(base: np.ndarray, other: np.ndarray) -> np.ndarray:
     overhead = overhead[filter_arr]
     # sort for hist and cdf purposes
     overhead.sort()
-    print(
-        f"n_sample {len(overhead)} avg {np.average(overhead):.2f} std {np.std(overhead):.2f}"
-    )
+    print_summary(base, other)
     return overhead
 
 
+def print_summary(base: np.ndarray, other: np.ndarray) -> None:
+    baseline = np.min(base)
+    concurent = np.min(other)
+    overhead = (concurent - baseline) / baseline * 100.0
+    print(f"min(base) = {baseline} min(data) = {concurent}")
+    print(f"overhead(min(base),min(data)) = {overhead:.2f}%\n")
+    baseline = np.average(base)
+    concurent = np.average(other)
+    overhead = (concurent - baseline) / baseline * 100.0
+    print(f"avg(base) = {baseline} avg(data) = {concurent}")
+    print(f"avg(min(base),avg(data)) = {overhead:.2f}%\n")
+    baseline = np.std(base)
+    concurent = np.std(other)
+    overhead = np.std((other - base) / base * 100.0)
+    print(f"std(base) = {baseline} std(data) = {concurent}")
+    print(f"std(overhead) = {overhead:.2f}\n")
+
+
 def plot_likelyhood(
     path: str, n_iter: int, task_dur: int, reac: int, measurements: list[str]
 ):
@@ -163,21 +185,25 @@ def plot_likelyhood(
     print("repeat =", len(df))
     assert "Baseline" in df.columns
     base = df["Baseline"].values
-    overheads = {
-        m: get_overhead(base, df[m].values) for m in measurements if m != "Baseline"
-    }
-    for label, overhead in overheads.items():
-        plt.plot(overhead, np.linspace(0, 1, len(overhead)), label=label)
-    plt.xlabel("x in %")
-    plt.ylabel("P(X < x)")
+    # overheads = {
+    # m: get_overhead(base, df[m].values) for m in measurements if m != "Baseline"
+    # }
+    # for label, overhead in overheads.items():
+    #     plt.plot(overhead, np.linspace(0, 1, len(overhead)), label=label)
+    # plt.xlabel("x in %")
+    # plt.ylabel("P(X < x)")
+    # plt.legend()
+    # plt.title("Probability than the real overhead is below x")
+    # for rate in (0.85, 0.90, 0.95, 0.99):
+    #     print(f"Probability than overhead is below x with {100*rate:.0f}% confidence :")
+    #     for label, sorted_data in overheads.items():
+    #         idx = int(rate * len(sorted_data))
+    #         x_rate = sorted_data[idx]
+    #         print(f"\t{label} x={x_rate:.2f}%")
+    x = np.arange(len(base))
+    plt.plot(x, df["Preemptive"].values, label="Preemptive")
+    plt.plot(x, df["Preemptive2"].values, label="Preemptive2")
     plt.legend()
-    plt.title("Probability than the real overhead is below x")
-    for rate in (0.85, 0.90, 0.95, 0.99):
-        print(f"Probability than overhead is below x with {100*rate:.0f}% confidence :")
-        for label, sorted_data in overheads.items():
-            idx = int(rate * len(sorted_data))
-            x_rate = sorted_data[idx]
-            print(f"\t{label} x={x_rate:.2f}%")
     plt.show()
 
 
@@ -285,6 +311,8 @@ def main():
             )
         case other:
             print(f"Unknown command: {other}")
+            print("See --help for valid subcommands")
+            exit(1)
 
 
 if __name__ == "__main__":
-- 
GitLab