{"id":17476688,"url":"https://github.com/rfgplk/bbench","last_synced_at":"2026-02-04T16:06:48.820Z","repository":{"id":258287772,"uuid":"871763744","full_name":"rfgplk/bbench","owner":"rfgplk","description":"a lightweight Linux benchmarking library written in C++20","archived":false,"fork":false,"pushed_at":"2025-09-12T19:45:06.000Z","size":95,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-12T21:59:53.234Z","etag":null,"topics":["bench","benchmark","benchmark-suite","cpp","cpp20","cpp20-library","header-only","microbenchmark","single-header","single-header-library"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rfgplk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-10-12T21:38:39.000Z","updated_at":"2025-09-12T19:45:10.000Z","dependencies_parsed_at":"2025-09-12T21:21:51.410Z","dependency_job_id":"9a53465b-4607-4fe7-b15f-57edb5c8b41f","html_url":"https://github.com/rfgplk/bbench","commit_stats":{"total_commits":5,"total_committers":2,"mean_commits":2.5,"dds":"0.19999999999999996","last_synced_commit":"585ea52bd34d0009e26c0e2c8c2d2217f6b2071a"},"previous_names":["rfgplk/bbench"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/rfgplk/bbench","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rfgplk%2Fbbench","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rfgplk%2Fbbench/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rfgplk%2Fbbench/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rfgplk%2Fbbench/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rfgplk","download_url":"https://codeload.github.com/rfgplk/bbench/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rfgplk%2Fbbench/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29089921,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-04T03:31:03.593Z","status":"ssl_error","status_checked_at":"2026-02-04T03:29:50.742Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bench","benchmark","benchmark-suite","cpp","cpp20","cpp20-library","header-only","microbenchmark","single-header","single-header-library"],"created_at":"2024-10-18T19:09:17.982Z","updated_at":"2026-02-04T16:06:48.815Z","avatar_url":"https://github.com/rfgplk.png","language":"C++","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/9d07b433-174a-4a63-a5f7-404c0224b0f4\" alt=\"bbench_logo_384\" width=\"300\"/\u003e\n  \n# bbench\n### a lightweight Linux performance event benchmarking library\n\u003c/div\u003e\n\nbbench is a *lightweight*, **intuitive**, and ***logical*** benchmarking library, written in C++20. \n\nThe goal of this library is to provide simplistic yet useful functions for *timing and profiling* performance **critical** code. The library uses specific performance monitoring facilities (via the kernel) to extract all the relevant information you would ever need without being overbearing. Most bbench code is evaluated and instantiated at compile time, meaning this is practically the *lightest (and smallest) possible implementation* of benchmarking functionality. Has minimal (almost non-existent) runtime overhead. It can be used either as a library or a compiled binary (in case you would like to benchmark precompiled code). \n\nTo compile from source run `ninja bbench` or `ninja btime`. \n\n\nbbench is specifically designed for Linux, as such other operating systems and kernels are entirely unsupported for the time being.\n\n## General Usage\n```cpp\n// Primary functions\nbenchmark_t  bbench::benchmark                 (Func, Arguments...);\nbenchmark_t  bbench::benchmark\u003ctime_unit\u003e      (Func, Arguments...);\nbenchmark_t  bbench::benchmark_bin             (path_to_binary, argv...);\n     double  bbench::bench                     (Func, Arguments...);\n     double  bbench::bench\u003ctime_unit\u003e          (Func, Arguments...);\n  long long  bbench::cpu_bench                 (Func, Arguments...);\n  long long  bbench::cpu_bench\u003ctarget_type\u003e    (Func, Arguments...);\n     double  bbench::bench_bin                 (path_to_binary, argv...);\n     double  bbench::bench_bin\u003ctime_unit\u003e      (path_to_binary, argv...);\n  long long  bbench::cpu_bench_bin             (path_to_binary, argv...);\n  long long  bbench::cpu_bench_bin\u003ctarget_type\u003e(path_to_binary, argv...);\n// path_to_binary can be either a const char* or any string-like object, same as argv\n// Func can be any function, Arguments can be of any type, ... denotes a variadic argument\n```\n## Specific Usage\n\n```cpp\nstd::vector\u003cdouble\u003e bbench::bench\u003ctime_unit\u003e (Funcs...);\nstd::vector\u003cdouble\u003e bbench::bench_repeat\u003cN\u003e  (Func, Arguments...);\n```\n\n### Example 0\n```cpp\n// call benchmark with a desired function and given time resolution to collect traced data\nbenchmark_t b = bbench::benchmark\u003cbbench::time_resolution::us\u003e  (parse_strings, \"test\", \"hello\", \"world\");\n// benchmark can be called with no template argument, in which case the resolution is assumed to be in us\n\n// benchmark primarily returns struct benchmark_t which holds all the traced data\nstruct benchmark_t {\n  double time;     // heh\n  long long cycles;\n  long long instructions;\n  long long cache_misses;\n  long long total_branches;\n  long long branch_misses;\n  long long total_cycles;\n  long long cpu_time;\n  long long context_switches;\n  long long migrations;\n\n  long long l1_cache;\n  long long l1t_cache;\n  long long ll_cache;\n  long long access;\n  long long bpu;\n};\n\n```\n\n\n### Example A\n```cpp\n#include \"src/bench.hpp\"\n\nauto bmx =   bbench::benchmark\u003cbbench::time_resolution::ns\u003e(my_function, arg1, arg2, arg3);\nstd::cout \u003c\u003c per_cycle(bmx) \u003c\u003c std::endl;\nstd::cout \u003c\u003c per_instruction(bmx) \u003c\u003c std::endl;\nstd::cout \u003c\u003c miss_percent(bmx) \u003c\u003c std::endl;\nstd::cout \u003c\u003c cycles_per_instruction(bmx) \u003c\u003c std::endl;\n```\n\n\n### Example B\n```cpp\n#include \"src/bench.hpp\"\n\n// Exhaustive list of bench targets\n// Each call collects information for that target only\n// bbench provides k_* and a_* prefixed targets for kernel tracing but depending \n// on perf_event_paranoid you may need root capabilities\n// check sysctl kernel.perf_event_paranoid and capabilities(7)\nauto s = bbench::cpu_bench\u003cbbench::hardware_cycles\u003e       (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::hardware_instructions\u003e (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::cache_misses\u003e          (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::branches\u003e              (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::branch_misses\u003e         (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::total_cycles\u003e          (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::cpu_time\u003e              (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::context_switches\u003e      (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::proc_migrations\u003e       (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::level1d\u003e               (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::level1t\u003e               (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::llcache\u003e               (my_function, arg1, arg2, arg3);\nauto s = bbench::cpu_bench\u003cbbench::cache_node\u003e            (my_function, arg1, arg2, arg3);\n\n// get cycles spent in kernel space\nauto s = bbench::cpu_bench\u003cbbench::k_hardware_cycles\u003e     (my_function, arg1, arg2, arg3); \n```\n\n### Example C\n```cpp\n#include \"src/bench.hpp\"\n\n// Time Resolutions\n// sec, ds, ms, us, ns\n// long names are equivalent, ie seconds, deciseconds, milliseconds...\ndouble d = bbench::bench\u003cbbench::time_resolution::ns\u003e     (my_function, arg1, arg2, arg3); \n// get time in ns\ndouble d = bbench::bench\u003cbbench::time_resolution::ms\u003e     (my_function, arg1, arg2, arg3); \n// get time in ms\n```\n\n### Example D\n```cpp\n#include \"src/bench.hpp\"\n\n// To bench a precompiled binary simply call any *_bin suffixed function\ndouble f = bbench::bench_bin(\"/bin/gcc\", \"a.cc\"); // equivalent to typing /bin/gcc a.cc into a shell\ndouble f = bbench::bench_bin(\"/bin/whoami\");\ndouble f = bbench::bench_bin(\"/bin/top\");\ndouble f = bbench::bench_bin(\"/bin/cal\");\n// path can be absolute or relative, strings following the first argument correspond to argv which the binary will receive\n// NOTE: if a relative path is provided, the binary must be present at that exact location\n// bbench DOES NOT check your local path, NOR does it invoke a shell\n```\n\n## Comparison with perf stat\nTested against perf, sample output for both executables.\n```\nPerformance counter stats for './bin/bbench /bin/whoami':\n\n              4.40 msec task-clock:u                     #    0.949 CPUs utilized             \n                 0      context-switches:u               #    0.000 /sec                      \n                 0      cpu-migrations:u                 #    0.000 /sec                      \n               211      page-faults:u                    #   47.939 K/sec                     \n         2,687,746      cycles:u                         #    0.611 GHz                         (95.77%)\n         3,712,006      instructions:u                   #    1.38  insn per cycle              (76.46%)\n           500,349      branches:u                       #  113.679 M/sec                     \n            15,581      branch-misses:u                  #    3.11% of all branches           \n\n       0.004640276 seconds time elapsed\n\n       0.001053000 seconds user\n       0.003764000 seconds sys\n\n\n Performance counter stats for 'perf stat whoami':\n\n             11.79 msec task-clock:u                     #    0.952 CPUs utilized             \n                 0      context-switches:u               #    0.000 /sec                      \n                 0      cpu-migrations:u                 #    0.000 /sec                      \n             1,066      page-faults:u                    #   90.430 K/sec                     \n        12,829,132      cycles:u                         #    1.088 GHz                       \n        15,285,441      instructions:u                   #    1.19  insn per cycle            \n         3,170,034      branches:u                       #  268.917 M/sec                     \n           109,362      branch-misses:u                  #    3.45% of all branches           \n\n       0.012379547 seconds time elapsed\n\n       0.005142000 seconds user\n       0.007240000 seconds sys\n\n// bbench output\n./bin/bbench /bin/whoami\nTotal time elapsed:   1241\nCycles Spent:         480439\nTotal Instructions:   384592\nTotal Branches:       88495\nBranch Misses:        5397\nTotal CPU Cycles:     840030\nTotal CPU Time Spent: 1096229\nContext Switches:     0\nCore Migrations:      0\nCache Misses:         2901\nL1 Cache:             0\nL1T Cache:            0\nLast Level Cache:     0\nCache Accesses:       0\nBranch Predictions:   0\n\nPerformance counter stats for '/bin/whoami':\n\n              0.76 msec task-clock:u                     #    0.654 CPUs utilized             \n                 0      context-switches:u               #    0.000 /sec                      \n                 0      cpu-migrations:u                 #    0.000 /sec                      \n                70      page-faults:u                    #   91.829 K/sec                     \n           574,814      cycles:u                         #    0.754 GHz                       \n           386,162      instructions:u                   #    0.67  insn per cycle            \n            88,976      branches:u                       #  116.722 M/sec                     \n             5,315      branch-misses:u                  #    5.97% of all branches           \n\n       0.001164855 seconds time elapsed\n\n       0.001215000 seconds user\n       0.000000000 seconds sys\n\n\n```\n\n\n\n## Installation\n\nbbench is a header only library. Just copy all files from `src/` and include `src/bench.hpp` into your project.To install bbench and btime simply run `ninja btime` and `ninja bbench` and copy the files to your desired location.\n\n\n## TODO\n- [ ] add direct __rdtsc functionality\n- [ ] develop benchmarking suites\n- [ ] write per core and per socket specific tracing core\n- [ ] develop benchmarking endpoints for all perf_event code (currently in bbench, but inaccessible easily)\n- [ ] write go \\\u0026 python wrappers\n- [ ] C bindings\n\n## Misc\nno external dependencies, requires C++20, tested with g++.\nRequires at least Linux 2.6.\nbbench needs the following headers (and associated .so) to compile properly (normally are distributed with every standard Linux/C++ distribution).\n\n```cpp\n#include \u003carray\u003e\n#include \u003cchrono\u003e\n#include \u003cconcepts\u003e\n#include \u003ccstdint\u003e\n#include \u003ccstdlib\u003e\n#include \u003ccstring\u003e\n#include \u003cexception\u003e\n#include \u003ciostream\u003e\n#include \u003clinux/perf_event.h\u003e\n#include \u003cmemory\u003e\n#include \u003cqueue\u003e\n#include \u003csched.h\u003e\n#include \u003csignal.h\u003e\n#include \u003cspawn.h\u003e\n#include \u003cstdexcept\u003e\n#include \u003cstdlib.h\u003e\n#include \u003cstring\u003e\n#include \u003csys/ioctl.h\u003e\n#include \u003csys/mman.h\u003e\n#include \u003csys/syscall.h\u003e\n#include \u003csys/types.h\u003e\n#include \u003csys/wait.h\u003e\n#include \u003ctime.h\u003e\n#include \u003ctype_traits\u003e\n#include \u003cunistd.h\u003e\n#include \u003cutility\u003e\n#include \u003cvariant\u003e\n#include \u003cvector\u003e\n```\n\n## License\nLicensed under the Boost Software License.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frfgplk%2Fbbench","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frfgplk%2Fbbench","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frfgplk%2Fbbench/lists"}