Showing preview only (1,040K chars total). Download the full file or copy to clipboard to get everything.
Repository: google/benchmark
Branch: main
Commit: d4393d5445b4
Files: 203
Total size: 983.8 KB
Directory structure:
gitextract_rtytoi0j/
├── .bazelversion
├── .clang-format
├── .clang-tidy
├── .clang-tidy.ignore
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── dependabot.yml
│ ├── install_bazel.sh
│ ├── libcxx-setup.sh
│ └── workflows/
│ ├── bazel.yml
│ ├── build-and-test-min-cmake.yml
│ ├── build-and-test-perfcounters.yml
│ ├── build-and-test.yml
│ ├── clang-format-lint.yml
│ ├── clang-tidy-lint.yml
│ ├── doxygen.yml
│ ├── ossf.yml
│ ├── pre-commit.yml
│ ├── sanitizer.yml
│ ├── test_bindings.yml
│ └── wheels.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .ycm_extra_conf.py
├── AUTHORS
├── BUILD.bazel
├── CMakeLists.txt
├── CONTRIBUTING.md
├── CONTRIBUTORS
├── LICENSE
├── MODULE.bazel
├── README.md
├── WORKSPACE
├── WORKSPACE.bzlmod
├── _config.yml
├── appveyor.yml
├── bazel/
│ └── benchmark_deps.bzl
├── bindings/
│ └── python/
│ └── google_benchmark/
│ ├── BUILD
│ ├── __init__.py
│ ├── benchmark.cc
│ └── example.py
├── cmake/
│ ├── AddCXXCompilerFlag.cmake
│ ├── CXXFeatureCheck.cmake
│ ├── Config.cmake.in
│ ├── GetGitVersion.cmake
│ ├── GoogleTest.cmake
│ ├── GoogleTest.cmake.in
│ ├── benchmark.pc.in
│ ├── benchmark_main.pc.in
│ ├── gnu_posix_regex.cpp
│ ├── llvm-toolchain.cmake
│ ├── posix_regex.cpp
│ ├── pthread_affinity.cpp
│ ├── split_list.cmake
│ ├── std_regex.cpp
│ ├── steady_clock.cpp
│ └── thread_safety_attributes.cpp
├── docs/
│ ├── AssemblyTests.md
│ ├── _config.yml
│ ├── assets/
│ │ └── images/
│ │ ├── icon.xcf
│ │ └── icon_black.xcf
│ ├── dependencies.md
│ ├── index.md
│ ├── perf_counters.md
│ ├── platform_specific_build_instructions.md
│ ├── python_bindings.md
│ ├── random_interleaving.md
│ ├── reducing_variance.md
│ ├── releasing.md
│ ├── tools.md
│ └── user_guide.md
├── include/
│ └── benchmark/
│ ├── benchmark.h
│ ├── benchmark_api.h
│ ├── counter.h
│ ├── export.h
│ ├── macros.h
│ ├── managers.h
│ ├── registration.h
│ ├── reporter.h
│ ├── state.h
│ ├── statistics.h
│ ├── sysinfo.h
│ ├── types.h
│ └── utils.h
├── pyproject.toml
├── setup.py
├── src/
│ ├── CMakeLists.txt
│ ├── arraysize.h
│ ├── benchmark.cc
│ ├── benchmark_api_internal.cc
│ ├── benchmark_api_internal.h
│ ├── benchmark_main.cc
│ ├── benchmark_name.cc
│ ├── benchmark_register.cc
│ ├── benchmark_register.h
│ ├── benchmark_runner.cc
│ ├── benchmark_runner.h
│ ├── check.cc
│ ├── check.h
│ ├── colorprint.cc
│ ├── colorprint.h
│ ├── commandlineflags.cc
│ ├── commandlineflags.h
│ ├── complexity.cc
│ ├── complexity.h
│ ├── console_reporter.cc
│ ├── counter.cc
│ ├── counter.h
│ ├── csv_reporter.cc
│ ├── cycleclock.h
│ ├── internal_macros.h
│ ├── json_reporter.cc
│ ├── log.h
│ ├── mutex.h
│ ├── perf_counters.cc
│ ├── perf_counters.h
│ ├── re.h
│ ├── reporter.cc
│ ├── statistics.cc
│ ├── statistics.h
│ ├── string_util.cc
│ ├── string_util.h
│ ├── sysinfo.cc
│ ├── thread_manager.h
│ ├── thread_timer.h
│ ├── timers.cc
│ └── timers.h
├── test/
│ ├── AssemblyTests.cmake
│ ├── BUILD
│ ├── CMakeLists.txt
│ ├── args_product_test.cc
│ ├── basic_test.cc
│ ├── benchmark_gtest.cc
│ ├── benchmark_min_time_flag_iters_test.cc
│ ├── benchmark_min_time_flag_time_test.cc
│ ├── benchmark_name_gtest.cc
│ ├── benchmark_random_interleaving_gtest.cc
│ ├── benchmark_setup_teardown_cb_types_gtest.cc
│ ├── benchmark_setup_teardown_test.cc
│ ├── benchmark_test.cc
│ ├── clobber_memory_assembly_test.cc
│ ├── commandlineflags_gtest.cc
│ ├── complexity_test.cc
│ ├── cxx11_test.cc
│ ├── diagnostics_test.cc
│ ├── display_aggregates_only_test.cc
│ ├── donotoptimize_assembly_test.cc
│ ├── donotoptimize_test.cc
│ ├── filter_test.cc
│ ├── fixture_test.cc
│ ├── internal_threading_test.cc
│ ├── link_main_test.cc
│ ├── locale_impermeability_test.cc
│ ├── manual_threading_test.cc
│ ├── map_test.cc
│ ├── memory_manager_test.cc
│ ├── memory_results_gtest.cc
│ ├── min_time_parse_gtest.cc
│ ├── multiple_ranges_test.cc
│ ├── options_test.cc
│ ├── output_test.h
│ ├── output_test_helper.cc
│ ├── overload_test.cc
│ ├── perf_counters_gtest.cc
│ ├── perf_counters_test.cc
│ ├── profiler_manager_gtest.cc
│ ├── profiler_manager_iterations_test.cc
│ ├── profiler_manager_test.cc
│ ├── register_benchmark_test.cc
│ ├── repetitions_test.cc
│ ├── report_aggregates_only_test.cc
│ ├── reporter_output_test.cc
│ ├── skip_with_error_test.cc
│ ├── spec_arg_test.cc
│ ├── spec_arg_verbosity_test.cc
│ ├── state_assembly_test.cc
│ ├── statistics_gtest.cc
│ ├── string_util_gtest.cc
│ ├── templated_fixture_method_test.cc
│ ├── templated_fixture_test.cc
│ ├── time_unit_gtest.cc
│ ├── user_counters_tabular_test.cc
│ ├── user_counters_test.cc
│ ├── user_counters_thousands_test.cc
│ └── user_counters_threads_test.cc
└── tools/
├── BUILD.bazel
├── compare.py
├── gbench/
│ ├── Inputs/
│ │ ├── test1_run1.json
│ │ ├── test1_run2.json
│ │ ├── test2_run.json
│ │ ├── test3_run0.json
│ │ ├── test3_run1.json
│ │ ├── test4_run.json
│ │ ├── test4_run0.json
│ │ ├── test4_run1.json
│ │ ├── test5_run0.json
│ │ └── test5_run1.json
│ ├── __init__.py
│ ├── report.py
│ └── util.py
├── libpfm.BUILD.bazel
├── requirements.txt
└── strip_asm.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .bazelversion
================================================
8.2.1
================================================
FILE: .clang-format
================================================
---
Language: Cpp
BasedOnStyle: Google
PointerAlignment: Left
...
================================================
FILE: .clang-tidy
================================================
---
Checks: >
abseil-*,
bugprone-*,
clang-analyzer-*,
cppcoreguidelines-*,
google-*,
misc-*,
performance-*,
readability-*,
-clang-analyzer-deadcode*,
-clang-analyzer-optin*,
-readability-identifier-length
WarningsAsErrors: ''
HeaderFilterRegex: ''
FormatStyle: none
CheckOptions:
llvm-else-after-return.WarnOnConditionVariables: 'false'
modernize-loop-convert.MinConfidence: reasonable
modernize-replace-auto-ptr.IncludeStyle: llvm
cert-str34-c.DiagnoseSignedUnsignedCharComparisons: 'false'
google-readability-namespace-comments.ShortNamespaceLines: '10'
cert-err33-c.CheckedFunctions: '::aligned_alloc;::asctime_s;::at_quick_exit;::atexit;::bsearch;::bsearch_s;::btowc;::c16rtomb;::c32rtomb;::calloc;::clock;::cnd_broadcast;::cnd_init;::cnd_signal;::cnd_timedwait;::cnd_wait;::ctime_s;::fclose;::fflush;::fgetc;::fgetpos;::fgets;::fgetwc;::fopen;::fopen_s;::fprintf;::fprintf_s;::fputc;::fputs;::fputwc;::fputws;::fread;::freopen;::freopen_s;::fscanf;::fscanf_s;::fseek;::fsetpos;::ftell;::fwprintf;::fwprintf_s;::fwrite;::fwscanf;::fwscanf_s;::getc;::getchar;::getenv;::getenv_s;::gets_s;::getwc;::getwchar;::gmtime;::gmtime_s;::localtime;::localtime_s;::malloc;::mbrtoc16;::mbrtoc32;::mbsrtowcs;::mbsrtowcs_s;::mbstowcs;::mbstowcs_s;::memchr;::mktime;::mtx_init;::mtx_lock;::mtx_timedlock;::mtx_trylock;::mtx_unlock;::printf_s;::putc;::putwc;::raise;::realloc;::remove;::rename;::scanf;::scanf_s;::setlocale;::setvbuf;::signal;::snprintf;::snprintf_s;::sprintf;::sprintf_s;::sscanf;::sscanf_s;::strchr;::strerror_s;::strftime;::strpbrk;::strrchr;::strstr;::strtod;::strtof;::strtoimax;::strtok;::strtok_s;::strtol;::strtold;::strtoll;::strtoul;::strtoull;::strtoumax;::strxfrm;::swprintf;::swprintf_s;::swscanf;::swscanf_s;::thrd_create;::thrd_detach;::thrd_join;::thrd_sleep;::time;::timespec_get;::tmpfile;::tmpfile_s;::tmpnam;::tmpnam_s;::tss_create;::tss_get;::tss_set;::ungetc;::ungetwc;::vfprintf;::vfprintf_s;::vfscanf;::vfscanf_s;::vfwprintf;::vfwprintf_s;::vfwscanf;::vfwscanf_s;::vprintf_s;::vscanf;::vscanf_s;::vsnprintf;::vsnprintf_s;::vsprintf;::vsprintf_s;::vsscanf;::vsscanf_s;::vswprintf;::vswprintf_s;::vswscanf;::vswscanf_s;::vwprintf_s;::vwscanf;::vwscanf_s;::wcrtomb;::wcschr;::wcsftime;::wcspbrk;::wcsrchr;::wcsrtombs;::wcsrtombs_s;::wcsstr;::wcstod;::wcstof;::wcstoimax;::wcstok;::wcstok_s;::wcstol;::wcstold;::wcstoll;::wcstombs;::wcstombs_s;::wcstoul;::wcstoull;::wcstoumax;::wcsxfrm;::wctob;::wctrans;::wctype;::wmemchr;::wprintf_s;::wscanf;::wscanf_s;'
cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField: 'false'
cert-dcl16-c.NewSuffixes: 'L;LL;LU;LLU'
google-readability-braces-around-statements.ShortStatementLines: '1'
cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'true'
google-readability-namespace-comments.SpacesBeforeComments: '2'
modernize-loop-convert.MaxCopySize: '16'
modernize-pass-by-value.IncludeStyle: llvm
modernize-use-nullptr.NullMacros: 'NULL'
llvm-qualified-auto.AddConstToQualified: 'false'
modernize-loop-convert.NamingStyle: CamelCase
llvm-else-after-return.WarnOnUnfixable: 'false'
google-readability-function-size.StatementThreshold: '800'
...
================================================
FILE: .clang-tidy.ignore
================================================
.*third_party/.*
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**System**
Which OS, compiler, and compiler version are you using:
- OS:
- Compiler and version:
**To reproduce**
Steps to reproduce the behavior:
1. sync to commit ...
2. cmake/bazel...
3. make ...
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: "[FR]"
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: daily
- package-ecosystem: pip
directory: /tools
schedule:
interval: daily
================================================
FILE: .github/install_bazel.sh
================================================
if ! bazel version; then
arch=$(uname -m)
if [ "$arch" == "aarch64" ]; then
arch="arm64"
fi
echo "Downloading $arch Bazel binary from GitHub releases."
curl -L -o $HOME/bin/bazel --create-dirs "https://github.com/bazelbuild/bazel/releases/download/8.2.0/bazel-8.2.0-linux-$arch"
chmod +x $HOME/bin/bazel
else
# Bazel is installed for the correct architecture
exit 0
fi
================================================
FILE: .github/libcxx-setup.sh
================================================
#!/usr/bin/env bash
set -e
# Checkout LLVM sources
git clone --filter=blob:none --depth=1 --branch llvmorg-19.1.6 --no-checkout https://github.com/llvm/llvm-project.git llvm-project
cd llvm-project
git sparse-checkout set --cone
git checkout llvmorg-19.1.6
git sparse-checkout set cmake llvm/cmake runtimes libcxx libcxxabi
cd ..
## Setup libc++ options
if [ -z "$BUILD_32_BITS" ]; then
export BUILD_32_BITS=OFF && echo disabling 32 bit build
fi
## Build and install libc++ (Use unstable ABI for better sanitizer coverage)
mkdir llvm-build && cd llvm-build
cmake -GNinja \
-DCMAKE_C_COMPILER=${CC} \
-DCMAKE_CXX_COMPILER=${CXX} \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX=/usr \
-DLIBCXX_ABI_UNSTABLE=OFF \
-DLLVM_USE_SANITIZER=${LIBCXX_SANITIZER} \
-DLLVM_BUILD_32_BITS=${BUILD_32_BITS} \
-DLIBCXXABI_USE_LLVM_UNWINDER=OFF \
-DLLVM_INCLUDE_TESTS=OFF \
-DLIBCXX_INCLUDE_TESTS=OFF \
-DLIBCXX_INCLUDE_BENCHMARKS=OFF \
-DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi' \
../llvm-project/runtimes/
cmake --build . -- cxx cxxabi
cd ..
================================================
FILE: .github/workflows/bazel.yml
================================================
name: bazel
on:
push: {}
pull_request: {}
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
build_and_test_default:
name: bazel.${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: mount bazel cache
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
env:
cache-name: bazel-cache
with:
path: "~/.cache/bazel"
key: ${{ env.cache-name }}-${{ matrix.os }}-${{ github.ref }}
restore-keys: |
${{ env.cache-name }}-${{ matrix.os }}-main
- name: build
run: |
bazel build //:benchmark //:benchmark_main //test/...
- name: test
run: |
bazel test --test_output=all //test/...
================================================
FILE: .github/workflows/build-and-test-min-cmake.yml
================================================
name: build-and-test-min-cmake
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
CMAKE_GENERATOR: Ninja
jobs:
job:
name: ${{ matrix.os }}.min-cmake
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: lukka/get-cmake@b78306120111dc2522750771cfd09ee7ca723687 # latest
with:
cmakeVersion: 3.13.0
- name: create build environment
run: cmake -E make_directory ${{ runner.workspace }}/_build
- name: setup cmake initial cache
run: touch compiler-cache.cmake
- name: configure cmake
env:
CXX: ${{ matrix.compiler }}
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: >
cmake -C ${{ github.workspace }}/compiler-cache.cmake
$GITHUB_WORKSPACE
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DCMAKE_CXX_VISIBILITY_PRESET=hidden
-DCMAKE_VISIBILITY_INLINES_HIDDEN=ON
- name: build
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: cmake --build .
================================================
FILE: .github/workflows/build-and-test-perfcounters.yml
================================================
name: build-and-test-perfcounters
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
job:
# TODO(dominic): Extend this to include compiler and set through env: CC/CXX.
name: ${{ matrix.os }}.${{ matrix.build_type }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
build_type: ['Release', 'Debug']
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: install libpfm
run: |
sudo apt update
sudo apt -y install libpfm4-dev
- name: create build environment
run: cmake -E make_directory ${{ runner.workspace }}/_build
- name: configure cmake
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: >
cmake $GITHUB_WORKSPACE
-DBENCHMARK_ENABLE_LIBPFM=1
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
- name: build
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: cmake --build . --config ${{ matrix.build_type }}
# Skip testing, for now. It seems perf_event_open does not succeed on the
# hosting machine, very likely a permissions issue.
# TODO(mtrofin): Enable test.
# - name: test
# shell: bash
# working-directory: ${{ runner.workspace }}/_build
# run: ctest -C ${{ matrix.build_type }} --rerun-failed --output-on-failure
================================================
FILE: .github/workflows/build-and-test.yml
================================================
name: build-and-test
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
CMAKE_GENERATOR: Ninja
jobs:
# TODO: add 32-bit builds (g++ and clang++) for ubuntu
# (requires g++-multilib and libc6:i386)
# TODO: add coverage build (requires lcov)
# TODO: add clang + libc++ builds for ubuntu
job:
name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.compiler }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, ubuntu-22.04, ubuntu-24.04-arm, macos-latest]
build_type: ['Release', 'Debug']
compiler: ['g++', 'clang++']
lib: ['shared', 'static']
steps:
- name: Install dependencies (macos)
if: runner.os == 'macOS'
run: brew install ninja
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: build
uses: threeal/cmake-action@725d1314ccf9ea922805d7e3f9d9bcbca892b406 # v2.1.0
with:
build-dir: ${{ runner.workspace }}/_build
cxx-compiler: ${{ matrix.compiler }}
options: |
BENCHMARK_DOWNLOAD_DEPENDENCIES=ON
BUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
CMAKE_BUILD_TYPE=${{ matrix.build_type }}
CMAKE_CXX_COMPILER=${{ matrix.compiler }}
CMAKE_CXX_VISIBILITY_PRESET=hidden
CMAKE_VISIBILITY_INLINES_HIDDEN=ON
- name: test
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: ctest -C ${{ matrix.build_type }} -VV
msvc:
name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.msvc }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: powershell
strategy:
fail-fast: false
matrix:
msvc:
- VS-17-2025
- VS-17-2022
build_type:
- Debug
- Release
lib:
- shared
- static
include:
- msvc: VS-17-2025
os: windows-2025
generator: 'Visual Studio 17 2022'
- msvc: VS-17-2022
os: windows-2022
generator: 'Visual Studio 17 2022'
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: lukka/get-cmake@b78306120111dc2522750771cfd09ee7ca723687 # latest
- name: configure cmake
run: >
cmake -S . -B ${{ runner.workspace }}/_build/
-G "${{ matrix.generator }}"
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
- name: build
run: cmake --build ${{ runner.workspace }}/_build/ --config ${{ matrix.build_type }}
- name: test
run: ctest --test-dir ${{ runner.workspace }}/_build/ -C ${{ matrix.build_type }} -VV
msys2:
name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.msys2.msystem }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: false
matrix:
os: [ windows-latest ]
msys2:
- { msystem: MINGW64, arch: x86_64, family: GNU, compiler: g++ }
- { msystem: CLANG64, arch: x86_64, family: LLVM, compiler: clang++ }
- { msystem: UCRT64, arch: x86_64, family: GNU, compiler: g++ }
build_type:
- Debug
- Release
lib:
- shared
- static
steps:
- name: setup msys2
uses: msys2/setup-msys2@4f806de0a5a7294ffabaff804b38a9b435a73bda # v2.30.0
with:
cache: false
msystem: ${{ matrix.msys2.msystem }}
update: true
install: >-
git
base-devel
pacboy: >-
gcc:p
clang:p
cmake:p
ninja:p
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# NOTE: we can't use cmake actions here as we need to do everything in msys2 shell.
- name: configure cmake
env:
CXX: ${{ matrix.msys2.compiler }}
run: >
cmake -S . -B _build/
-GNinja
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
- name: build
run: cmake --build _build/ --config ${{ matrix.build_type }}
- name: test
working-directory: _build
run: ctest -C ${{ matrix.build_type }} -VV
================================================
FILE: .github/workflows/clang-format-lint.yml
================================================
name: clang-format-lint
on:
push: {}
pull_request: {}
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
job:
name: check-clang-format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: DoozyX/clang-format-lint-action@bcb4eb2cb0d707ee4f3e5cc3b456eb075f12cf73 # v0.20
with:
source: './include/benchmark ./src ./test ./bindings'
clangFormatVersion: 18
================================================
FILE: .github/workflows/clang-tidy-lint.yml
================================================
name: clang-tidy
on:
push: {}
pull_request: {}
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
job:
name: run-clang-tidy
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: install clang-tidy
run: sudo apt update && sudo apt -y install clang-tidy
- name: create build environment
run: cmake -E make_directory ${{ github.workspace }}/_build
- name: configure cmake
shell: bash
working-directory: ${{ github.workspace }}/_build
run: >
cmake $GITHUB_WORKSPACE
-DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF
-DBENCHMARK_ENABLE_LIBPFM=OFF
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DCMAKE_C_COMPILER=clang
-DCMAKE_CXX_COMPILER=clang++
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-DGTEST_COMPILE_COMMANDS=OFF
- name: run
shell: bash
working-directory: ${{ github.workspace }}/_build
run: run-clang-tidy -config-file=$GITHUB_WORKSPACE/.clang-tidy
================================================
FILE: .github/workflows/doxygen.yml
================================================
name: doxygen
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
build-and-deploy:
name: Build HTML documentation
runs-on: ubuntu-latest
steps:
- name: Fetching sources
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Installing build dependencies
run: |
sudo apt update
sudo apt install doxygen gcc git
- name: Creating build directory
run: mkdir build
- name: Building HTML documentation with Doxygen
run: |
cmake -S . -B build -DBENCHMARK_ENABLE_TESTING:BOOL=OFF -DBENCHMARK_ENABLE_DOXYGEN:BOOL=ON -DBENCHMARK_INSTALL_DOCS:BOOL=ON
cmake --build build --target benchmark_doxygen
================================================
FILE: .github/workflows/ossf.yml
================================================
name: OSSF Scorecard Weekly
on:
schedule:
- cron: '0 0 * * 0' # Runs every Sunday at midnight UTC
workflow_dispatch:
permissions:
contents: read
jobs:
ossf-scorecard:
# To write a badge
permissions:
id-token: write
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run analysis
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
with:
publish_results: true
results_file: ossf_scorecard.json
results_format: json
================================================
FILE: .github/workflows/pre-commit.yml
================================================
name: python + Bazel pre-commit checks
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
python-version: 3.12
- name: Run pre-commit checks
run: uv run --only-group=dev pre-commit run --all-files --verbose --show-diff-on-failure
================================================
FILE: .github/workflows/sanitizer.yml
================================================
name: sanitizer
on:
push: {}
pull_request: {}
env:
CMAKE_GENERATOR: Ninja
UBSAN_OPTIONS: "print_stacktrace=1"
jobs:
job:
name: ${{ matrix.sanitizer }}.${{ matrix.build_type }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
build_type: ['Debug', 'RelWithDebInfo']
sanitizer: ['asan', 'ubsan', 'tsan', 'msan']
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: configure msan env
if: matrix.sanitizer == 'msan'
run: |
echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=memory -fsanitize-memory-track-origins" >> $GITHUB_ENV
echo "LIBCXX_SANITIZER=MemoryWithOrigins" >> $GITHUB_ENV
- name: configure ubsan env
if: matrix.sanitizer == 'ubsan'
run: |
echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all" >> $GITHUB_ENV
echo "LIBCXX_SANITIZER=Undefined" >> $GITHUB_ENV
- name: configure asan env
if: matrix.sanitizer == 'asan'
run: |
echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=address -fno-sanitize-recover=all" >> $GITHUB_ENV
echo "LIBCXX_SANITIZER=Address" >> $GITHUB_ENV
- name: configure tsan env
if: matrix.sanitizer == 'tsan'
run: |
echo "EXTRA_FLAGS=-g -O2 -fno-omit-frame-pointer -fsanitize=thread -fno-sanitize-recover=all" >> $GITHUB_ENV
echo "LIBCXX_SANITIZER=Thread" >> $GITHUB_ENV
- name: fine-tune asan options
# in asan we get an error from std::regex. ignore it.
if: matrix.sanitizer == 'asan'
run: |
echo "ASAN_OPTIONS=alloc_dealloc_mismatch=0" >> $GITHUB_ENV
- name: setup clang
uses: egor-tensin/setup-clang@471a6f8ef1d449dba8e1a51780e7f943572a3f99 # v2.1
with:
version: latest
platform: x64
- name: configure clang
run: |
echo "CC=cc" >> $GITHUB_ENV
echo "CXX=c++" >> $GITHUB_ENV
- name: build libc++ (non-asan)
if: matrix.sanitizer != 'asan'
run: |
"${GITHUB_WORKSPACE}/.github/libcxx-setup.sh"
echo "EXTRA_CXX_FLAGS=-stdlib=libc++ -L${GITHUB_WORKSPACE}/llvm-build/lib -lc++abi -I${GITHUB_WORKSPACE}/llvm-build/include/c++/v1 -Isystem${GITHUB_WORKSPACE}/llvm-build/include/c++/v1 -Wl,-rpath,${GITHUB_WORKSPACE}/llvm-build/lib" >> $GITHUB_ENV
- name: create build environment
run: cmake -E make_directory ${{ runner.workspace }}/_build
- name: configure cmake
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: >
VERBOSE=1
cmake -GNinja $GITHUB_WORKSPACE
-DBENCHMARK_ENABLE_ASSEMBLY_TESTS=OFF
-DBENCHMARK_ENABLE_LIBPFM=OFF
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
-DCMAKE_C_COMPILER=${{ env.CC }}
-DCMAKE_CXX_COMPILER=${{ env.CXX }}
-DCMAKE_C_FLAGS="${{ env.EXTRA_FLAGS }}"
-DCMAKE_CXX_FLAGS="${{ env.EXTRA_FLAGS }} ${{ env.EXTRA_CXX_FLAGS }}"
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
- name: build
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: cmake --build . --config ${{ matrix.build_type }}
- name: test
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: ctest -C ${{ matrix.build_type }} -VV
================================================
FILE: .github/workflows/test_bindings.yml
================================================
name: test-bindings
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
CMAKE_GENERATOR: Ninja
permissions:
contents: read
jobs:
python_bindings:
name: Test GBM Python ${{ matrix.python-version }} bindings on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ]
python-version: [ "3.10", "3.11", "3.12", "3.13" ]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ matrix.python-version }}
- name: Install GBM Python bindings on ${{ matrix.os }}
run: python -m pip install .
- name: Run example on ${{ matrix.os }} under Python ${{ matrix.python-version }}
run: python bindings/python/google_benchmark/example.py
================================================
FILE: .github/workflows/wheels.yml
================================================
name: Build and upload Python wheels
on:
workflow_dispatch:
release:
types:
- published
env:
CMAKE_GENERATOR: Ninja
jobs:
build_sdist:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Install Python 3.12
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.12"
- run: python -m pip install build
- name: Build sdist
run: python -m build --sdist
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: dist-sdist
path: dist/*.tar.gz
build_wheels:
name: Build Google Benchmark wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest, windows-latest]
steps:
- name: Check out Google Benchmark
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
name: Install Python 3.12
with:
python-version: "3.12"
- name: Install the latest version of uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
- name: Build wheels on ${{ matrix.os }} using cibuildwheel
uses: pypa/cibuildwheel@ee02a1537ce3071a004a6b08c41e72f0fdc42d9a # v3.4.0
env:
CIBW_BUILD: "cp310-* cp311-* cp312-*"
CIBW_BUILD_FRONTEND: "build[uv]"
CIBW_SKIP: "*-musllinux_*"
CIBW_ARCHS: auto64
CIBW_BEFORE_ALL_LINUX: bash .github/install_bazel.sh
# Grab the rootless Bazel installation inside the container.
CIBW_ENVIRONMENT_LINUX: PATH=$PATH:$HOME/bin
CIBW_TEST_COMMAND: python {project}/bindings/python/google_benchmark/example.py
# unused by Bazel, but needed explicitly by delocate on MacOS.
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.os == 'macos-15-intel' && 10.14 || 11.0 }}
- name: Upload Google Benchmark ${{ matrix.os }} wheels
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: dist-${{ matrix.os }}
path: wheelhouse/*.whl
pypi_upload:
name: Publish google-benchmark wheels to PyPI
needs: [build_sdist, build_wheels]
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: dist
pattern: dist-*
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
================================================
FILE: .gitignore
================================================
*.a
*.so
*.so.?*
*.dll
*.exe
*.dylib
*.cmake
!/cmake/*.cmake
!/test/AssemblyTests.cmake
*~
*.swp
*.pyc
__pycache__
.DS_Store
# lcov
*.lcov
/lcov
# cmake files.
/Testing
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
# makefiles.
Makefile
# in-source build.
bin/
lib/
/test/*_test
# exuberant ctags.
tags
# YouCompleteMe configuration.
.ycm_extra_conf.pyc
# ninja generated files.
.ninja_deps
.ninja_log
build.ninja
install_manifest.txt
rules.ninja
# bazel output symlinks.
bazel-*
MODULE.bazel.lock
# out-of-source build top-level folders.
build/
_build/
build*/
# in-source dependencies
/googletest/
# Visual Studio 2015/2017 cache/options directory
.vs/
CMakeSettings.json
# Visual Studio Code cache/options directory
.vscode/
# Python build stuff
dist/
*.egg-info*
uv.lock
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://github.com/keith/pre-commit-buildifier
rev: 8.2.1
hooks:
- id: buildifier
- id: buildifier-lint
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.18.2
hooks:
- id: mypy
types_or: [ python, pyi ]
args: [ "--ignore-missing-imports", "--scripts-are-modules" ]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.0
hooks:
- id: ruff-check
args: [ --fix, --exit-non-zero-on-fix ]
- id: ruff-format
================================================
FILE: .ycm_extra_conf.py
================================================
import os
import ycm_core
# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
"-Wall",
"-Werror",
"-pedantic-errors",
"-std=c++0x",
"-fno-strict-aliasing",
"-O3",
"-DNDEBUG",
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to 'c' instead of 'c++'.
"-x",
"c++",
"-I",
"include",
"-isystem",
"/usr/include",
"-isystem",
"/usr/local/include",
]
# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ""
if os.path.exists(compilation_database_folder):
database = ycm_core.CompilationDatabase(compilation_database_folder)
else:
database = None
SOURCE_EXTENSIONS = [".cc"]
def DirectoryOfThisScript():
return os.path.dirname(os.path.abspath(__file__))
def MakeRelativePathsInFlagsAbsolute(flags, working_directory):
if not working_directory:
return list(flags)
new_flags = []
make_next_absolute = False
path_flags = ["-isystem", "-I", "-iquote", "--sysroot="]
for flag in flags:
new_flag = flag
if make_next_absolute:
make_next_absolute = False
if not flag.startswith("/"):
new_flag = os.path.join(working_directory, flag)
for path_flag in path_flags:
if flag == path_flag:
make_next_absolute = True
break
if flag.startswith(path_flag):
path = flag[len(path_flag) :]
new_flag = path_flag + os.path.join(working_directory, path)
break
if new_flag:
new_flags.append(new_flag)
return new_flags
def IsHeaderFile(filename):
extension = os.path.splitext(filename)[1]
return extension in [".h", ".hxx", ".hpp", ".hh"]
def GetCompilationInfoForFile(filename):
# The compilation_commands.json file generated by CMake does not have
# entries for header files. So we do our best by asking the db for flags for
# a corresponding source file, if any. If one exists, the flags for that
# file should be good enough.
if IsHeaderFile(filename):
basename = os.path.splitext(filename)[0]
for extension in SOURCE_EXTENSIONS:
replacement_file = basename + extension
if os.path.exists(replacement_file):
compilation_info = database.GetCompilationInfoForFile(
replacement_file
)
if compilation_info.compiler_flags_:
return compilation_info
return None
return database.GetCompilationInfoForFile(filename)
def FlagsForFile(filename, **kwargs):
if database:
# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object
compilation_info = GetCompilationInfoForFile(filename)
if not compilation_info:
return None
final_flags = MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_,
)
else:
relative_to = DirectoryOfThisScript()
final_flags = MakeRelativePathsInFlagsAbsolute(flags, relative_to)
return {"flags": final_flags, "do_cache": True}
================================================
FILE: AUTHORS
================================================
# This is the official list of benchmark authors for copyright purposes.
# This file is distinct from the CONTRIBUTORS files.
# See the latter for an explanation.
#
# Names should be added to this file as:
# Name or Organization <email address>
# The email address is not required for organizations.
#
# Please keep the list sorted.
Albert Pretorius <pretoalb@gmail.com>
Alex Steele <steeleal123@gmail.com>
Andriy Berestovskyy <berestovskyy@gmail.com>
Arne Beer <arne@twobeer.de>
Benjamin King <kingbenja5@gmail.com>
Carto
Cezary Skrzyński <czars1988@gmail.com>
Christian Wassermann <christian_wassermann@web.de>
Christopher Seymour <chris.j.seymour@hotmail.com>
Colin Braley <braley.colin@gmail.com>
Daniel Harvey <danielharvey458@gmail.com>
David Coeurjolly <david.coeurjolly@liris.cnrs.fr>
Deniz Evrenci <denizevrenci@gmail.com>
Dirac Research
Dominik Czarnota <dominik.b.czarnota@gmail.com>
Dominik Korman <kormandominik@gmail.com>
Donald Aingworth <donalds_junk_mail@yahoo.com>
Eric Backus <eric_backus@alum.mit.edu>
Eric Fiselier <eric@efcs.ca>
Eugene Zhuk <eugene.zhuk@gmail.com>
Evgeny Safronov <division494@gmail.com>
Fabien Pichot <pichot.fabien@gmail.com>
Federico Ficarelli <federico.ficarelli@gmail.com>
Felix Homann <linuxaudio@showlabor.de>
Gergely Meszaros <maetveis@gmail.com>
Gergő Szitár <szitar.gergo@gmail.com>
Google Inc.
Henrique Bucher <hbucher@gmail.com>
International Business Machines Corporation
Ismael Jimenez Martinez <ismael.jimenez.martinez@gmail.com>
Jern-Kuan Leong <jernkuan@gmail.com>
JianXiong Zhou <zhoujianxiong2@gmail.com>
Joao Paulo Magalhaes <joaoppmagalhaes@gmail.com>
Jordan Williams <jwillikers@protonmail.com>
Jussi Knuuttila <jussi.knuuttila@gmail.com>
Kaito Udagawa <umireon@gmail.com>
Kishan Kumar <kumar.kishan@outlook.com>
Kostiantyn Lazukin <konstantin.lazukin@gmail.com>
Lei Xu <eddyxu@gmail.com>
Marcel Jacobse <mjacobse@uni-bremen.de>
Matt Clarkson <mattyclarkson@gmail.com>
Maxim Vafin <maxvafin@gmail.com>
Mike Apodaca <gatorfax@gmail.com>
Min-Yih Hsu <yihshyng223@gmail.com>
MongoDB Inc.
Nick Hutchinson <nshutchinson@gmail.com>
Norman Heino <norman.heino@gmail.com>
Oleksandr Sochka <sasha.sochka@gmail.com>
Olga Fadeeva <olga.kiselik@gmail.com>
Ori Livneh <ori.livneh@gmail.com>
Paul Redmond <paul.redmond@gmail.com>
Prithvi Rao <ee22b024@smail.iitm.ac.in>
Radoslav Yovchev <radoslav.tm@gmail.com>
Raghu Raja <raghu@enfabrica.net>
Rainer Orth <ro@cebitec.uni-bielefeld.de>
Roman Lebedev <lebedev.ri@gmail.com>
Sayan Bhattacharjee <aero.sayan@gmail.com>
Shapr3D <google-contributors@shapr3d.com>
Shashank Thakur <shashankt2004@gmail.com>
Shuo Chen <chenshuo@chenshuo.com>
Staffan Tjernstrom <staffantj@gmail.com>
Steinar H. Gunderson <sgunderson@bigfoot.com>
Stripe, Inc.
Tobias Schmidt <tobias.schmidt@in.tum.de>
Yixuan Qiu <yixuanq@gmail.com>
Yusuke Suzuki <utatane.tea@gmail.com>
Zbigniew Skowron <zbychs@gmail.com>
================================================
FILE: BUILD.bazel
================================================
load("@rules_cc//cc:defs.bzl", "cc_library")
licenses(["notice"])
COPTS = [
"-pedantic",
"-pedantic-errors",
"-std=c++17",
"-Wall",
"-Wconversion",
"-Wextra",
"-Wshadow",
# "-Wshorten-64-to-32",
"-Wfloat-equal",
"-Wformat=2",
"-fstrict-aliasing",
## assert() are used a lot in tests upstream, which may be optimised out leading to
## unused-variable warning.
"-Wno-unused-variable",
"-Werror=old-style-cast",
]
MSVC_COPTS = [
"/std:c++17",
]
config_setting(
name = "windows",
constraint_values = ["@platforms//os:windows"],
visibility = [":__subpackages__"],
)
config_setting(
name = "perfcounters",
define_values = {
"pfm": "1",
},
visibility = [":__subpackages__"],
)
cc_library(
name = "benchmark",
srcs = glob(
[
"src/*.cc",
"src/*.h",
],
exclude = ["src/benchmark_main.cc"],
),
hdrs = [
"include/benchmark/benchmark.h",
"include/benchmark/benchmark_api.h",
"include/benchmark/counter.h",
"include/benchmark/export.h",
"include/benchmark/macros.h",
"include/benchmark/managers.h",
"include/benchmark/registration.h",
"include/benchmark/reporter.h",
"include/benchmark/state.h",
"include/benchmark/statistics.h",
"include/benchmark/sysinfo.h",
"include/benchmark/types.h",
"include/benchmark/utils.h",
],
copts = select({
":windows": MSVC_COPTS,
"//conditions:default": COPTS,
}),
defines = [
"BENCHMARK_STATIC_DEFINE",
"BENCHMARK_VERSION=\\\"" + (module_version() if module_version() != None else "") + "\\\"",
] + select({
":perfcounters": ["HAVE_LIBPFM"],
"//conditions:default": [],
}),
includes = ["include"],
linkopts = select({
":windows": ["-DEFAULTLIB:shlwapi.lib"],
"//conditions:default": ["-pthread"],
}),
# Only static linking is allowed; no .so will be produced.
# Using `defines` (i.e. not `local_defines`) means that no
# dependent rules need to bother about defining the macro.
linkstatic = True,
local_defines = [
# Turn on Large-file Support
"_FILE_OFFSET_BITS=64",
"_LARGEFILE64_SOURCE",
"_LARGEFILE_SOURCE",
],
visibility = ["//visibility:public"],
deps = select({
":perfcounters": ["@libpfm"],
"//conditions:default": [],
}),
)
cc_library(
name = "benchmark_main",
srcs = ["src/benchmark_main.cc"],
hdrs = [
"include/benchmark/benchmark.h",
"include/benchmark/benchmark_api.h",
"include/benchmark/counter.h",
"include/benchmark/export.h",
"include/benchmark/macros.h",
"include/benchmark/managers.h",
"include/benchmark/registration.h",
"include/benchmark/reporter.h",
"include/benchmark/state.h",
"include/benchmark/statistics.h",
"include/benchmark/sysinfo.h",
"include/benchmark/types.h",
"include/benchmark/utils.h",
],
includes = ["include"],
visibility = ["//visibility:public"],
deps = [":benchmark"],
)
cc_library(
name = "benchmark_internal_headers",
hdrs = glob(["src/*.h"]),
visibility = ["//test:__pkg__"],
)
================================================
FILE: CMakeLists.txt
================================================
# Require CMake 3.10. If available, use the policies up to CMake 3.22.
cmake_minimum_required (VERSION 3.13...3.22)
project (benchmark VERSION 1.9.5 LANGUAGES CXX)
option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." ON)
option(BENCHMARK_ENABLE_EXCEPTIONS "Enable the use of exceptions in the benchmark library." ON)
option(BENCHMARK_ENABLE_LTO "Enable link time optimisation of the benchmark library." OFF)
option(BENCHMARK_USE_LIBCXX "Build and test using libc++ as the standard library." OFF)
option(BENCHMARK_ENABLE_WERROR "Build Release candidates with -Werror." ON)
option(BENCHMARK_FORCE_WERROR "Build Release candidates with -Werror regardless of compiler issues." OFF)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "PGI")
# PGC++ maybe reporting false positives.
set(BENCHMARK_ENABLE_WERROR OFF)
endif()
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "NVHPC")
set(BENCHMARK_ENABLE_WERROR OFF)
endif()
if(BENCHMARK_FORCE_WERROR)
set(BENCHMARK_ENABLE_WERROR ON)
endif(BENCHMARK_FORCE_WERROR)
if(NOT (MSVC OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))
option(BENCHMARK_BUILD_32_BITS "Build a 32 bit version of the library." OFF)
else()
set(BENCHMARK_BUILD_32_BITS OFF CACHE BOOL "Build a 32 bit version of the library - unsupported when using MSVC)" FORCE)
endif()
option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" ON)
option(BENCHMARK_ENABLE_DOXYGEN "Build documentation with Doxygen." OFF)
option(BENCHMARK_INSTALL_DOCS "Enable installation of documentation." ON)
option(BENCHMARK_INSTALL_TOOLS "Enable installation of tools." ON)
# Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which
# may require downloading the source code.
option(BENCHMARK_DOWNLOAD_DEPENDENCIES "Allow the downloading and in-tree building of unmet dependencies" OFF)
# This option can be used to disable building and running unit tests which depend on gtest
# in cases where it is not possible to build or find a valid version of gtest.
option(BENCHMARK_ENABLE_GTEST_TESTS "Enable building the unit tests which depend on gtest" ON)
option(BENCHMARK_USE_BUNDLED_GTEST "Use bundled GoogleTest. If disabled, the find_package(GTest) will be used." ON)
option(BENCHMARK_ENABLE_LIBPFM "Enable performance counters provided by libpfm" OFF)
# Export only public symbols
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# As of CMake 3.18, CMAKE_SYSTEM_PROCESSOR is not set properly for MSVC and
# cross-compilation (e.g. Host=x86_64, target=aarch64) requires using the
# undocumented, but working variable.
# See https://gitlab.kitware.com/cmake/cmake/-/issues/15170
set(CMAKE_SYSTEM_PROCESSOR ${MSVC_CXX_ARCHITECTURE_ID})
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ARM")
set(CMAKE_CROSSCOMPILING TRUE)
endif()
endif()
set(ENABLE_ASSEMBLY_TESTS_DEFAULT OFF)
function(should_enable_assembly_tests)
if(CMAKE_BUILD_TYPE)
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
if (${CMAKE_BUILD_TYPE_LOWER} MATCHES "coverage")
# FIXME: The --coverage flag needs to be removed when building assembly
# tests for this to work.
return()
endif()
endif()
if (MSVC OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
return()
elseif(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
return()
elseif(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
# FIXME: Make these work on 32 bit builds
return()
elseif(BENCHMARK_BUILD_32_BITS)
# FIXME: Make these work on 32 bit builds
return()
endif()
find_program(LLVM_FILECHECK_EXE FileCheck)
if (LLVM_FILECHECK_EXE)
set(LLVM_FILECHECK_EXE "${LLVM_FILECHECK_EXE}" CACHE PATH "llvm filecheck" FORCE)
message(STATUS "LLVM FileCheck Found: ${LLVM_FILECHECK_EXE}")
else()
message(STATUS "Failed to find LLVM FileCheck")
return()
endif()
set(ENABLE_ASSEMBLY_TESTS_DEFAULT ON PARENT_SCOPE)
endfunction()
should_enable_assembly_tests()
# This option disables the building and running of the assembly verification tests
option(BENCHMARK_ENABLE_ASSEMBLY_TESTS "Enable building and running the assembly tests"
${ENABLE_ASSEMBLY_TESTS_DEFAULT})
# Make sure we can import out CMake functions
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Read the git tags to determine the project version
include(GetGitVersion)
get_git_version(GIT_VERSION)
# If no git version can be determined, use the version
# from the project() command
if ("${GIT_VERSION}" STREQUAL "v0.0.0")
set(VERSION "v${benchmark_VERSION}")
else()
set(VERSION "${GIT_VERSION}")
endif()
# Normalize version: drop "v" prefix, replace first "-" with ".",
# drop everything after second "-" (including said "-").
string(STRIP ${VERSION} VERSION)
if(VERSION MATCHES v[^-]*-)
string(REGEX REPLACE "v([^-]*)-([0-9]+)-.*" "\\1.\\2" NORMALIZED_VERSION ${VERSION})
else()
string(REGEX REPLACE "v(.*)" "\\1" NORMALIZED_VERSION ${VERSION})
endif()
# Tell the user what versions we are using
message(STATUS "Google Benchmark version: ${VERSION}, normalized to ${NORMALIZED_VERSION}")
# The version of the libraries
set(GENERIC_LIB_VERSION ${NORMALIZED_VERSION})
string(SUBSTRING ${NORMALIZED_VERSION} 0 1 GENERIC_LIB_SOVERSION)
# Import our CMake modules
include(AddCXXCompilerFlag)
include(CheckCXXCompilerFlag)
include(CheckLibraryExists)
include(CXXFeatureCheck)
# Check for rt library, but explicitly disable for QNX
if(QNXNTO)
set(HAVE_LIB_RT FALSE)
else()
check_library_exists(rt shm_open "" HAVE_LIB_RT)
endif()
if (BENCHMARK_BUILD_32_BITS)
add_required_cxx_compiler_flag(-m32)
endif()
set(BENCHMARK_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD ${BENCHMARK_CXX_STANDARD})
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS OFF)
if (MSVC)
# Turn compiler warnings up to 11
string(REGEX REPLACE "[-/]W[1-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
# MP flag only applies to cl, not cl frontends to other compilers (e.g. clang-cl, icx-cl etc)
if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
endif()
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
if(BENCHMARK_ENABLE_WERROR)
add_cxx_compiler_flag(-WX)
endif()
if (NOT BENCHMARK_ENABLE_EXCEPTIONS)
add_cxx_compiler_flag(-EHs-)
add_cxx_compiler_flag(-EHa-)
add_definitions(-D_HAS_EXCEPTIONS=0)
endif()
# Link time optimisation
if (BENCHMARK_ENABLE_LTO)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /GL")
string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO}")
set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /GL")
set(CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL "${CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL} /LTCG")
set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} /LTCG")
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /LTCG")
endif()
else()
# Turn on Large-file Support
add_definitions(-D_FILE_OFFSET_BITS=64)
add_definitions(-D_LARGEFILE64_SOURCE)
add_definitions(-D_LARGEFILE_SOURCE)
# Turn compiler warnings up to 11
add_cxx_compiler_flag(-Wall)
add_cxx_compiler_flag(-Wextra)
add_cxx_compiler_flag(-Wshadow)
add_cxx_compiler_flag(-Wfloat-equal)
add_cxx_compiler_flag(-Wold-style-cast)
add_cxx_compiler_flag(-Wconversion)
add_cxx_compiler_flag(-Wformat=2)
if(BENCHMARK_ENABLE_WERROR)
add_cxx_compiler_flag(-Werror)
endif()
if (NOT BENCHMARK_ENABLE_TESTING)
# Disable warning when compiling tests as gtest does not use 'override'.
add_cxx_compiler_flag(-Wsuggest-override)
endif()
add_cxx_compiler_flag(-pedantic)
add_cxx_compiler_flag(-pedantic-errors)
add_cxx_compiler_flag(-Wshorten-64-to-32)
add_cxx_compiler_flag(-fstrict-aliasing)
# Disable warnings regarding deprecated parts of the library while building
# and testing those parts of the library.
add_cxx_compiler_flag(-Wno-deprecated-declarations)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel" OR CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM")
# Intel silently ignores '-Wno-deprecated-declarations',
# warning no. 1786 must be explicitly disabled.
# See #631 for rationale.
add_cxx_compiler_flag(-wd1786)
add_cxx_compiler_flag(-fno-finite-math-only)
# ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially
# overridden (because of deprecated overload)
add_cxx_compiler_flag(-wd654)
endif()
# Disable deprecation warnings for release builds (when -Werror is enabled).
if(BENCHMARK_ENABLE_WERROR)
add_cxx_compiler_flag(-Wno-deprecated)
endif()
if (NOT BENCHMARK_ENABLE_EXCEPTIONS)
add_cxx_compiler_flag(-fno-exceptions)
endif()
if (HAVE_CXX_FLAG_FSTRICT_ALIASING)
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") #ICC17u2: Many false positives for Wstrict-aliasing
add_cxx_compiler_flag(-Wstrict-aliasing)
endif()
endif()
add_cxx_compiler_flag(-Wthread-safety)
if (HAVE_CXX_FLAG_WTHREAD_SAFETY)
cxx_feature_check(THREAD_SAFETY_ATTRIBUTES "-DINCLUDE_DIRECTORIES=${PROJECT_SOURCE_DIR}/include")
endif()
# On most UNIX like platforms g++ and clang++ define _GNU_SOURCE as a
# predefined macro, which turns on all of the wonderful libc extensions.
# However g++ doesn't do this in Cygwin so we have to define it ourselves
# since we depend on GNU/POSIX/BSD extensions.
if (CYGWIN)
add_definitions(-D_GNU_SOURCE=1)
endif()
if (QNXNTO)
add_definitions(-D_QNX_SOURCE)
endif()
# Link time optimisation
if (BENCHMARK_ENABLE_LTO)
add_cxx_compiler_flag(-flto)
add_cxx_compiler_flag(-Wno-lto-type-mismatch)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
find_program(GCC_AR gcc-ar)
if (GCC_AR)
set(CMAKE_AR ${GCC_AR})
endif()
find_program(GCC_RANLIB gcc-ranlib)
if (GCC_RANLIB)
set(CMAKE_RANLIB ${GCC_RANLIB})
endif()
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
include(llvm-toolchain)
endif()
endif()
# Coverage build type
set(BENCHMARK_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG}"
CACHE STRING "Flags used by the C++ compiler during coverage builds."
FORCE)
set(BENCHMARK_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_DEBUG}"
CACHE STRING "Flags used for linking binaries during coverage builds."
FORCE)
set(BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}"
CACHE STRING "Flags used by the shared libraries linker during coverage builds."
FORCE)
mark_as_advanced(
BENCHMARK_CXX_FLAGS_COVERAGE
BENCHMARK_EXE_LINKER_FLAGS_COVERAGE
BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE)
set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.")
add_cxx_compiler_flag(--coverage COVERAGE)
endif()
if (BENCHMARK_USE_LIBCXX)
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
add_cxx_compiler_flag(-stdlib=libc++)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "IntelLLVM")
add_cxx_compiler_flag(-nostdinc++)
message(WARNING "libc++ header path must be manually specified using CMAKE_CXX_FLAGS")
# Adding -nodefaultlibs directly to CMAKE_<TYPE>_LINKER_FLAGS will break
# configuration checks such as 'find_package(Threads)'
list(APPEND BENCHMARK_CXX_LINKER_FLAGS -nodefaultlibs)
# -lc++ cannot be added directly to CMAKE_<TYPE>_LINKER_FLAGS because
# linker flags appear before all linker inputs and -lc++ must appear after.
list(APPEND BENCHMARK_CXX_LIBRARIES c++)
else()
message(FATAL_ERROR "-DBENCHMARK_USE_LIBCXX:BOOL=ON is not supported for compiler")
endif()
endif(BENCHMARK_USE_LIBCXX)
# C++ feature checks
# Determine the correct regular expression engine to use
cxx_feature_check(STD_REGEX)
cxx_feature_check(GNU_POSIX_REGEX)
cxx_feature_check(POSIX_REGEX)
if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)
message(FATAL_ERROR "Failed to determine the source files for the regular expression backend")
endif()
if (NOT BENCHMARK_ENABLE_EXCEPTIONS AND HAVE_STD_REGEX
AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)
message(WARNING "Using std::regex with exceptions disabled is not fully supported")
endif()
cxx_feature_check(STEADY_CLOCK)
# Ensure we have pthreads
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
# cxx_feature_check relies on try_run to probe compiler features. Because this
# check does not produce a real target, target_link_libraries cannot be applied.
# Therefore, link libraries are forwarded to try_run through
# BENCHMARK_CXX_LIBRARIES.
list(APPEND BENCHMARK_CXX_LIBRARIES Threads::Threads)
cxx_feature_check(PTHREAD_AFFINITY)
if (BENCHMARK_ENABLE_LIBPFM)
find_package(PFM REQUIRED)
endif()
# Set up directories
include_directories(${PROJECT_SOURCE_DIR}/include)
# Build the targets
add_subdirectory(src)
if (BENCHMARK_ENABLE_TESTING)
enable_testing()
if (BENCHMARK_ENABLE_GTEST_TESTS AND
NOT (TARGET gtest AND TARGET gtest_main AND
TARGET gmock AND TARGET gmock_main))
if (BENCHMARK_USE_BUNDLED_GTEST)
include(GoogleTest)
else()
find_package(GTest CONFIG REQUIRED)
add_library(gtest ALIAS GTest::gtest)
add_library(gtest_main ALIAS GTest::gtest_main)
add_library(gmock ALIAS GTest::gmock)
add_library(gmock_main ALIAS GTest::gmock_main)
endif()
endif()
add_subdirectory(test)
endif()
================================================
FILE: CONTRIBUTING.md
================================================
# How to contribute #
We'd love to accept your patches and contributions to this project. There are
a just a few small guidelines you need to follow.
## Contributor License Agreement ##
Contributions to any Google project must be accompanied by a Contributor
License Agreement. This is not a copyright **assignment**, it simply gives
Google permission to use and redistribute your contributions as part of the
project.
* If you are an individual writing original source code and you're sure you
own the intellectual property, then you'll need to sign an [individual
CLA][].
* If you work for a company that wants to allow you to contribute your work,
then you'll need to sign a [corporate CLA][].
You generally only need to submit a CLA once, so if you've already submitted
one (even if it was for a different project), you probably don't need to do it
again.
[individual CLA]: https://developers.google.com/open-source/cla/individual
[corporate CLA]: https://developers.google.com/open-source/cla/corporate
Once your CLA is submitted (or if you already submitted one for
another Google project), make a commit adding yourself to the
[AUTHORS][] and [CONTRIBUTORS][] files. This commit can be part
of your first [pull request][].
[AUTHORS]: AUTHORS
[CONTRIBUTORS]: CONTRIBUTORS
## Submitting a patch ##
1. It's generally best to start by opening a new issue describing the bug or
feature you're intending to fix. Even if you think it's relatively minor,
it's helpful to know what people are working on. Mention in the initial
issue that you are planning to work on that bug or feature so that it can
be assigned to you.
1. Follow the normal process of [forking][] the project, and setup a new
branch to work in. It's important that each group of changes be done in
separate branches in order to ensure that a pull request only includes the
commits related to that bug or feature.
1. Do your best to have [well-formed commit messages][] for each change.
This provides consistency throughout the project, and ensures that commit
messages are able to be formatted properly by various git tools.
1. Finally, push the commits to your fork and submit a [pull request][].
[forking]: https://help.github.com/articles/fork-a-repo
[well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
[pull request]: https://help.github.com/articles/creating-a-pull-request
================================================
FILE: CONTRIBUTORS
================================================
# People who have agreed to one of the CLAs and can contribute patches.
# The AUTHORS file lists the copyright holders; this file
# lists people. For example, Google employees are listed here
# but not in AUTHORS, because Google holds the copyright.
#
# Names should be added to this file only after verifying that
# the individual or the individual's organization has agreed to
# the appropriate Contributor License Agreement, found here:
#
# https://developers.google.com/open-source/cla/individual
# https://developers.google.com/open-source/cla/corporate
#
# The agreement for individuals can be filled out on the web.
#
# When adding J Random Contributor's name to this file,
# either J's name or J's organization's name should be
# added to the AUTHORS file, depending on whether the
# individual or corporate CLA was used.
#
# Names should be added to this file as:
# Name <email address>
#
# Please keep the list sorted.
Abhina Sreeskantharajan <abhina.sreeskantharajan@ibm.com>
Albert Pretorius <pretoalb@gmail.com>
Alex Steele <steelal123@gmail.com>
Andriy Berestovskyy <berestovskyy@gmail.com>
Arne Beer <arne@twobeer.de>
Bátor Tallér <bator.taller@shapr3d.com>
Benjamin King <kingbenja5@gmail.com>
Billy Robert O'Neal III <billy.oneal@gmail.com> <bion@microsoft.com>
Cezary Skrzyński <czars1988@gmail.com>
Chris Kennelly <ckennelly@google.com> <ckennelly@ckennelly.com>
Christian Wassermann <christian_wassermann@web.de>
Christopher Seymour <chris.j.seymour@hotmail.com>
Colin Braley <braley.colin@gmail.com>
Cyrille Faucheux <cyrille.faucheux@gmail.com>
Daniel Harvey <danielharvey458@gmail.com>
David Coeurjolly <david.coeurjolly@liris.cnrs.fr>
Deniz Evrenci <denizevrenci@gmail.com>
Dominic Hamon <dma@stripysock.com> <dominic@google.com>
Dominik Czarnota <dominik.b.czarnota@gmail.com>
Dominik Korman <kormandominik@gmail.com>
Donald Aingworth <donalds_junk_mail@yahoo.com>
Doug Evans <xdje42@gmail.com>
Eric Backus <eric_backus@alum.mit.edu>
Eric Fiselier <eric@efcs.ca>
Eugene Zhuk <eugene.zhuk@gmail.com>
Evgeny Safronov <division494@gmail.com>
Fabien Pichot <pichot.fabien@gmail.com>
Fanbo Meng <fanbo.meng@ibm.com>
Federico Ficarelli <federico.ficarelli@gmail.com>
Felix Homann <linuxaudio@showlabor.de>
Geoffrey Martin-Noble <gcmn@google.com> <gmngeoffrey@gmail.com>
Gergely Meszaros <maetveis@gmail.com>
Gergő Szitár <szitar.gergo@gmail.com>
Hannes Hauswedell <h2@fsfe.org>
Henrique Bucher <hbucher@gmail.com>
Ismael Jimenez Martinez <ismael.jimenez.martinez@gmail.com>
Iakov Sergeev <yahontu@gmail.com>
Jern-Kuan Leong <jernkuan@gmail.com>
JianXiong Zhou <zhoujianxiong2@gmail.com>
Joao Paulo Magalhaes <joaoppmagalhaes@gmail.com>
John Millikin <jmillikin@stripe.com>
Jordan Williams <jwillikers@protonmail.com>
Jussi Knuuttila <jussi.knuuttila@gmail.com>
Kaito Udagawa <umireon@gmail.com>
Kai Wolf <kai.wolf@gmail.com>
Kishan Kumar <kumar.kishan@outlook.com>
Kostiantyn Lazukin <konstantin.lazukin@gmail.com>
Lei Xu <eddyxu@gmail.com>
Marcel Jacobse <mjacobse@uni-bremen.de>
Matt Clarkson <mattyclarkson@gmail.com>
Maxim Vafin <maxvafin@gmail.com>
Mike Apodaca <gatorfax@gmail.com>
Min-Yih Hsu <yihshyng223@gmail.com>
Nick Hutchinson <nshutchinson@gmail.com>
Norman Heino <norman.heino@gmail.com>
Oleksandr Sochka <sasha.sochka@gmail.com>
Olga Fadeeva <olga.kiselik@gmail.com>
Ori Livneh <ori.livneh@gmail.com>
Pascal Leroy <phl@google.com>
Paul Redmond <paul.redmond@gmail.com>
Pierre Phaneuf <pphaneuf@google.com>
Prithvi Rao <ee22b024@smail.iitm.ac.in>
Radoslav Yovchev <radoslav.tm@gmail.com>
Raghu Raja <raghu@enfabrica.net>
Rainer Orth <ro@cebitec.uni-bielefeld.de>
Raul Marin <rmrodriguez@cartodb.com>
Ray Glover <ray.glover@uk.ibm.com>
Robert Guo <robert.guo@mongodb.com>
Roman Lebedev <lebedev.ri@gmail.com>
Sayan Bhattacharjee <aero.sayan@gmail.com>
Shashank Thakur <shashankt2004@gmail.com>
ShengYi Hung <aokblast@FreeBSD.org>
Shuo Chen <chenshuo@chenshuo.com>
Steven Wan <wan.yu@ibm.com>
Tobias Schmidt <tobias.schmidt@in.tum.de>
Tobias Ulvgård <tobias.ulvgard@dirac.se>
Tom Madams <tom.ej.madams@gmail.com> <tmadams@google.com>
Yixuan Qiu <yixuanq@gmail.com>
Yusuke Suzuki <utatane.tea@gmail.com>
Zbigniew Skowron <zbychs@gmail.com>
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: MODULE.bazel
================================================
module(
name = "google_benchmark",
version = "1.9.5",
)
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "rules_cc", version = "0.0.9")
bazel_dep(name = "rules_python", version = "1.0.0", dev_dependency = True)
bazel_dep(name = "googletest", version = "1.14.0", dev_dependency = True, repo_name = "com_google_googletest")
bazel_dep(name = "libpfm", version = "4.11.0.bcr.1")
# Register a toolchain for Python 3.9 to be able to build numpy. Python
# versions >=3.10 are problematic.
# A second reason for this is to be able to build Python hermetically instead
# of relying on the changing default version from rules_python.
python = use_extension("@rules_python//python/extensions:python.bzl", "python", dev_dependency = True)
python.toolchain(python_version = "3.8")
python.toolchain(python_version = "3.9")
python.toolchain(python_version = "3.10")
python.toolchain(python_version = "3.11")
python.toolchain(
is_default = True,
python_version = "3.12",
)
python.toolchain(python_version = "3.13")
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip", dev_dependency = True)
pip.parse(
hub_name = "tools_pip_deps",
python_version = "3.12",
requirements_lock = "//tools:requirements.txt",
)
use_repo(pip, "tools_pip_deps")
# -- bazel_dep definitions -- #
bazel_dep(name = "nanobind_bazel", version = "2.9.2", dev_dependency = True)
================================================
FILE: README.md
================================================
# Benchmark
[](https://github.com/google/benchmark/actions?query=workflow%3Abuild-and-test)
[](https://github.com/google/benchmark/actions/workflows/bazel.yml)
[](https://github.com/google/benchmark/actions?query=workflow%3Atest-bindings)
[](https://coveralls.io/r/google/benchmark)
[](https://securityscorecards.dev/viewer/?uri=github.com/google/benchmark)
[](https://discord.gg/cz7UX7wKC2)
A library to benchmark code snippets, similar to unit tests. Example:
```c++
#include <benchmark/registration.h>
#include <benchmark/state.h>
static void BM_SomeFunction(benchmark::State& state) {
// Perform setup here
for (auto _ : state) {
// This code gets timed
SomeFunction();
}
}
// Register the function as a benchmark
BENCHMARK(BM_SomeFunction);
// Run the benchmark
BENCHMARK_MAIN();
```
## Getting Started
To get started, see [Requirements](#requirements) and
[Installation](#installation). See [Usage](#usage) for a full example and the
[User Guide](docs/user_guide.md) for a more comprehensive feature overview.
It may also help to read the [Google Test documentation](https://github.com/google/googletest/blob/main/docs/primer.md)
as some of the structural aspects of the APIs are similar.
## Resources
[Discussion group](https://groups.google.com/d/forum/benchmark-discuss)
IRC channels:
* [libera](https://libera.chat) #benchmark
[Additional Tooling Documentation](docs/tools.md)
[Assembly Testing Documentation](docs/AssemblyTests.md)
[Building and installing Python bindings](docs/python_bindings.md)
## Requirements
The library can be used with C++11. However, it requires C++17 to build,
including compiler and standard library support.
_See [dependencies.md](docs/dependencies.md) for more details regarding supported
compilers and standards._
If you have need for a particular compiler to be supported, patches are very welcome.
See [Platform-Specific Build Instructions](docs/platform_specific_build_instructions.md).
## Installation
This describes the installation process using cmake. As pre-requisites, you'll
need git and cmake installed.
_See [dependencies.md](docs/dependencies.md) for more details regarding supported
versions of build tools._
```bash
# Check out the library.
$ git clone https://github.com/google/benchmark.git
# Go to the library root directory
$ cd benchmark
# Make a build directory to place the build output.
$ cmake -E make_directory "build"
# Generate build system files with cmake, and download any dependencies.
$ cmake -E chdir "build" cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release ../
# or, starting with CMake 3.13, use a simpler form:
# cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=on -DCMAKE_BUILD_TYPE=Release -S . -B "build"
# Build the library.
$ cmake --build "build" --config Release
```
This builds the `benchmark` and `benchmark_main` libraries and tests.
On a unix system, the build directory should now look something like this:
```
/benchmark
/build
/src
/libbenchmark.a
/libbenchmark_main.a
/test
...
```
Next, you can run the tests to check the build.
```bash
$ cmake -E chdir "build" ctest --build-config Release
```
If you want to install the library globally, also run:
```
sudo cmake --build "build" --config Release --target install
```
Note that Google Benchmark requires Google Test to build and run the tests. This
dependency can be provided two ways:
* Checkout the Google Test sources into `benchmark/googletest`.
* Otherwise, if `-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON` is specified during
configuration as above, the library will automatically download and build
any required dependencies.
If you do not wish to build and run the tests, add `-DBENCHMARK_ENABLE_GTEST_TESTS=OFF`
to `CMAKE_ARGS`.
### Debug vs Release
By default, benchmark builds as a debug library. You will see a warning in the
output when this is the case. To build it as a release library instead, add
`-DCMAKE_BUILD_TYPE=Release` when generating the build system files, as shown
above. The use of `--config Release` in build commands is needed to properly
support multi-configuration tools (like Visual Studio for example) and can be
skipped for other build systems (like Makefile).
To enable link-time optimisation, also add `-DBENCHMARK_ENABLE_LTO=true` when
generating the build system files.
If you are using gcc, you might need to set `GCC_AR` and `GCC_RANLIB` cmake
cache variables, if autodetection fails.
If you are using clang, you may need to set `LLVMAR_EXECUTABLE`,
`LLVMNM_EXECUTABLE` and `LLVMRANLIB_EXECUTABLE` cmake cache variables.
To enable sanitizer checks (eg., `asan` and `tsan`), add:
```
-DCMAKE_C_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=address -fsanitize=thread -fno-sanitize-recover=all"
-DCMAKE_CXX_FLAGS="-g -O2 -fno-omit-frame-pointer -fsanitize=address -fsanitize=thread -fno-sanitize-recover=all "
```
### Stable and Experimental Library Versions
The main branch contains the latest stable version of the benchmarking library;
the API of which can be considered largely stable, with source breaking changes
being made only upon the release of a new major version.
Newer, experimental, features are implemented and tested on the
[`v2` branch](https://github.com/google/benchmark/tree/v2). Users who wish
to use, test, and provide feedback on the new features are encouraged to try
this branch. However, this branch provides no stability guarantees and reserves
the right to change and break the API at any time.
## Usage
### Basic usage
Define a function that executes the code to measure, register it as a benchmark
function using the `BENCHMARK` macro, and ensure an appropriate `main` function
is available:
```c++
#include <benchmark/benchmark.h>
static void BM_StringCreation(benchmark::State& state) {
for (auto _ : state)
std::string empty_string;
}
// Register the function as a benchmark
BENCHMARK(BM_StringCreation);
// Define another benchmark
static void BM_StringCopy(benchmark::State& state) {
std::string x = "hello";
for (auto _ : state)
std::string copy(x);
}
BENCHMARK(BM_StringCopy);
BENCHMARK_MAIN();
```
To run the benchmark, compile and link against the `benchmark` library
(libbenchmark.a/.so). If you followed the build steps above, this library will
be under the build directory you created.
```bash
# Example on linux after running the build steps above. Assumes the
# `benchmark` and `build` directories are under the current directory.
$ g++ mybenchmark.cc -std=c++11 -isystem benchmark/include \
-Lbenchmark/build/src -lbenchmark -lpthread -o mybenchmark
```
Alternatively, link against the `benchmark_main` library and remove
`BENCHMARK_MAIN();` above to get the same behavior.
The compiled executable will run all benchmarks by default. Pass the `--help`
flag for option information or see the [User Guide](docs/user_guide.md).
### Usage with CMake
If using CMake, it is recommended to link against the project-provided
`benchmark::benchmark` and `benchmark::benchmark_main` targets using
`target_link_libraries`.
It is possible to use ```find_package``` to import an installed version of the
library.
```cmake
find_package(benchmark REQUIRED)
```
Alternatively, ```add_subdirectory``` will incorporate the library directly in
to one's CMake project.
```cmake
add_subdirectory(benchmark)
```
Either way, link to the library as follows.
```cmake
target_link_libraries(MyTarget benchmark::benchmark)
```
================================================
FILE: WORKSPACE
================================================
workspace(name = "com_github_google_benchmark")
load("//:bazel/benchmark_deps.bzl", "benchmark_deps")
benchmark_deps()
load("@rules_python//python:repositories.bzl", "py_repositories")
py_repositories()
load("@rules_python//python:pip.bzl", "pip_parse")
pip_parse(
name = "tools_pip_deps",
requirements_lock = "//tools:requirements.txt",
)
load("@tools_pip_deps//:requirements.bzl", "install_deps")
install_deps()
================================================
FILE: WORKSPACE.bzlmod
================================================
# This file marks the root of the Bazel workspace.
# See MODULE.bazel for dependencies and setup.
================================================
FILE: _config.yml
================================================
theme: jekyll-theme-midnight
markdown: GFM
================================================
FILE: appveyor.yml
================================================
version: '{build}'
image: Visual Studio 2017
configuration:
- Debug
- Release
environment:
matrix:
- compiler: msvc-15-seh
generator: "Visual Studio 15 2017"
- compiler: msvc-15-seh
generator: "Visual Studio 15 2017 Win64"
- compiler: msvc-14-seh
generator: "Visual Studio 14 2015"
- compiler: msvc-14-seh
generator: "Visual Studio 14 2015 Win64"
- compiler: gcc-5.3.0-posix
generator: "MinGW Makefiles"
cxx_path: 'C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin'
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
matrix:
fast_finish: true
install:
# git bash conflicts with MinGW makefiles
- if "%generator%"=="MinGW Makefiles" (set "PATH=%PATH:C:\Program Files\Git\usr\bin;=%")
- if not "%cxx_path%"=="" (set "PATH=%PATH%;%cxx_path%")
build_script:
- md _build -Force
- cd _build
- echo %configuration%
- cmake -G "%generator%" "-DCMAKE_BUILD_TYPE=%configuration%" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON ..
- cmake --build . --config %configuration%
test_script:
- ctest --build-config %configuration% --timeout 300 --output-on-failure
artifacts:
- path: '_build/CMakeFiles/*.log'
name: logs
- path: '_build/Testing/**/*.xml'
name: test_results
================================================
FILE: bazel/benchmark_deps.bzl
================================================
"""
This file contains the Bazel build dependencies for Google Benchmark (both C++ source and Python bindings).
"""
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
def benchmark_deps():
"""Loads dependencies required to build Google Benchmark."""
if "bazel_skylib" not in native.existing_rules():
http_archive(
name = "bazel_skylib",
sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz",
],
)
if "rules_python" not in native.existing_rules():
http_archive(
name = "rules_python",
sha256 = "e85ae30de33625a63eca7fc40a94fea845e641888e52f32b6beea91e8b1b2793",
strip_prefix = "rules_python-0.27.1",
url = "https://github.com/bazelbuild/rules_python/releases/download/0.27.1/rules_python-0.27.1.tar.gz",
)
if "com_google_googletest" not in native.existing_rules():
new_git_repository(
name = "com_google_googletest",
remote = "https://github.com/google/googletest.git",
tag = "release-1.12.1",
)
if "nanobind" not in native.existing_rules():
new_git_repository(
name = "nanobind",
remote = "https://github.com/wjakob/nanobind.git",
tag = "v1.9.2",
build_file = "@//bindings/python:nanobind.BUILD",
recursive_init_submodules = True,
)
if "libpfm" not in native.existing_rules():
# Downloaded from v4.9.0 tag at https://sourceforge.net/p/perfmon2/libpfm4/ref/master/tags/
http_archive(
name = "libpfm",
build_file = str(Label("//tools:libpfm.BUILD.bazel")),
sha256 = "5da5f8872bde14b3634c9688d980f68bda28b510268723cc12973eedbab9fecc",
type = "tar.gz",
strip_prefix = "libpfm-4.11.0",
urls = ["https://sourceforge.net/projects/perfmon2/files/libpfm4/libpfm-4.11.0.tar.gz/download"],
)
================================================
FILE: bindings/python/google_benchmark/BUILD
================================================
load("@nanobind_bazel//:build_defs.bzl", "nanobind_extension", "nanobind_stubgen")
load("@rules_python//python:defs.bzl", "py_library", "py_test")
py_library(
name = "google_benchmark",
srcs = ["__init__.py"],
visibility = ["//visibility:public"],
deps = [
":_benchmark",
],
)
nanobind_extension(
name = "_benchmark",
srcs = ["benchmark.cc"],
deps = ["//:benchmark"],
)
nanobind_stubgen(
name = "benchmark_stubgen",
marker_file = "bindings/python/google_benchmark/py.typed",
module = ":_benchmark",
)
py_test(
name = "example",
srcs = ["example.py"],
python_version = "PY3",
srcs_version = "PY3",
visibility = ["//visibility:public"],
deps = [
":google_benchmark",
],
)
================================================
FILE: bindings/python/google_benchmark/__init__.py
================================================
# Copyright 2020 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Python benchmarking utilities.
Example usage:
import google_benchmark as benchmark
@benchmark.register
def my_benchmark(state):
... # Code executed outside `while` loop is not timed.
while state:
... # Code executed within `while` loop is timed.
if __name__ == '__main__':
benchmark.main()
"""
import atexit
from google_benchmark import _benchmark
from google_benchmark._benchmark import (
Counter as Counter,
State as State,
kMicrosecond as kMicrosecond,
kMillisecond as kMillisecond,
kNanosecond as kNanosecond,
kSecond as kSecond,
o1 as o1,
oAuto as oAuto,
oLambda as oLambda,
oLogN as oLogN,
oN as oN,
oNCubed as oNCubed,
oNLogN as oNLogN,
oNone as oNone,
oNSquared as oNSquared,
)
__version__ = "1.9.5"
class __OptionMaker:
"""A stateless class to collect benchmark options.
Collect all decorator calls like @option.range(start=0, limit=1<<5).
"""
class Options:
"""Pure data class to store options calls, along with the benchmarked
function."""
def __init__(self, func):
self.func = func
self.builder_calls = []
@classmethod
def make(cls, func_or_options):
"""Make Options from Options or the benchmarked function."""
if isinstance(func_or_options, cls.Options):
return func_or_options
return cls.Options(func_or_options)
def __getattr__(self, builder_name):
"""Append option call in the Options."""
# The function that get returned on @option.range(start=0, limit=1<<5).
def __builder_method(*args, **kwargs):
# The decorator that get called, either with the benchmared function
# or the previous Options
def __decorator(func_or_options):
options = self.make(func_or_options)
options.builder_calls.append((builder_name, args, kwargs))
# The decorator returns Options so it is not technically a
# decorator and needs a final call to @register
return options
return __decorator
return __builder_method
# Alias for nicer API.
# We have to instantiate an object, even if stateless, to be able to use
# __getattr__ on option.range
option = __OptionMaker()
def register(undefined=None, *, name=None):
"""Register function for benchmarking."""
if undefined is None:
# Decorator is called without parenthesis so we return a decorator
return lambda f: register(f, name=name)
# We have either the function to benchmark (simple case) or an instance of
# Options (@option._ case).
options = __OptionMaker.make(undefined)
if name is None:
name = options.func.__name__
# We register the benchmark and reproduce all the @option._ calls onto the
# benchmark builder pattern
benchmark = _benchmark.RegisterBenchmark(name, options.func)
for name, args, kwargs in options.builder_calls[::-1]:
getattr(benchmark, name)(*args, **kwargs)
# return the benchmarked function because the decorator does not modify it
return options.func
def main(argv: list[str] | None = None) -> None:
import sys
_benchmark.Initialize(argv or sys.argv)
return _benchmark.RunSpecifiedBenchmarks()
# FIXME: can we rerun with disabled ASLR?
# Methods for use with custom main function.
initialize = _benchmark.Initialize
run_benchmarks = _benchmark.RunSpecifiedBenchmarks
add_custom_context = _benchmark.AddCustomContext
atexit.register(_benchmark.ClearRegisteredBenchmarks)
================================================
FILE: bindings/python/google_benchmark/benchmark.cc
================================================
// Benchmark for Python.
#include "benchmark/benchmark.h"
#include "nanobind/nanobind.h"
#include "nanobind/operators.h"
#include "nanobind/stl/bind_map.h"
#include "nanobind/stl/string.h"
#include "nanobind/stl/vector.h"
NB_MAKE_OPAQUE(benchmark::UserCounters);
namespace {
namespace nb = nanobind;
std::vector<std::string> Initialize(const std::vector<std::string>& argv) {
std::vector<char*> ptrs;
ptrs.reserve(argv.size());
for (auto& arg : argv) {
ptrs.push_back(const_cast<char*>(arg.c_str()));
}
if (!ptrs.empty()) {
// The `argv` pointers here become invalid when this function returns, but
// benchmark holds the pointer to `argv[0]`. We create a static copy of it
// so it persists, and replace the pointer below.
static std::string executable_name(argv[0]);
ptrs[0] = const_cast<char*>(executable_name.c_str());
}
int argc = static_cast<int>(argv.size());
benchmark::Initialize(&argc, ptrs.data());
std::vector<std::string> remaining_argv;
remaining_argv.reserve(argc);
for (int i = 0; i < argc; ++i) {
remaining_argv.emplace_back(ptrs[i]);
}
return remaining_argv;
}
benchmark::Benchmark* RegisterBenchmark(const std::string& name,
nb::callable f) {
return benchmark::RegisterBenchmark(
name, [f](benchmark::State& state) { f(&state); });
}
NB_MODULE(_benchmark, m) {
using benchmark::TimeUnit;
nb::enum_<TimeUnit>(m, "TimeUnit")
.value("kNanosecond", TimeUnit::kNanosecond)
.value("kMicrosecond", TimeUnit::kMicrosecond)
.value("kMillisecond", TimeUnit::kMillisecond)
.value("kSecond", TimeUnit::kSecond)
.export_values();
using benchmark::BigO;
nb::enum_<BigO>(m, "BigO")
.value("oNone", BigO::oNone)
.value("o1", BigO::o1)
.value("oN", BigO::oN)
.value("oNSquared", BigO::oNSquared)
.value("oNCubed", BigO::oNCubed)
.value("oLogN", BigO::oLogN)
.value("oNLogN", BigO::oNLogN)
.value("oAuto", BigO::oAuto)
.value("oLambda", BigO::oLambda)
.export_values();
using benchmark::Benchmark;
nb::class_<Benchmark>(m, "Benchmark")
// For methods returning a pointer to the current object, reference
// return policy is used to ask nanobind not to take ownership of the
// returned object and avoid calling delete on it.
// https://pybind11.readthedocs.io/en/stable/advanced/functions.html#return-value-policies
//
// For methods taking a const std::vector<...>&, a copy is created
// because a it is bound to a Python list.
// https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html
.def("unit", &Benchmark::Unit, nb::rv_policy::reference)
.def("arg", &Benchmark::Arg, nb::rv_policy::reference)
.def("args", &Benchmark::Args, nb::rv_policy::reference)
.def("range", &Benchmark::Range, nb::rv_policy::reference,
nb::arg("start"), nb::arg("limit"))
.def("dense_range", &Benchmark::DenseRange, nb::rv_policy::reference,
nb::arg("start"), nb::arg("limit"), nb::arg("step") = 1)
.def("ranges", &Benchmark::Ranges, nb::rv_policy::reference)
.def("args_product", &Benchmark::ArgsProduct, nb::rv_policy::reference)
.def("arg_name", &Benchmark::ArgName, nb::rv_policy::reference)
.def("arg_names", &Benchmark::ArgNames, nb::rv_policy::reference)
.def("range_pair", &Benchmark::RangePair, nb::rv_policy::reference,
nb::arg("lo1"), nb::arg("hi1"), nb::arg("lo2"), nb::arg("hi2"))
.def("range_multiplier", &Benchmark::RangeMultiplier,
nb::rv_policy::reference)
.def("min_time", &Benchmark::MinTime, nb::rv_policy::reference)
.def("min_warmup_time", &Benchmark::MinWarmUpTime,
nb::rv_policy::reference)
.def("iterations", &Benchmark::Iterations, nb::rv_policy::reference)
.def("repetitions", &Benchmark::Repetitions, nb::rv_policy::reference)
.def("report_aggregates_only", &Benchmark::ReportAggregatesOnly,
nb::rv_policy::reference, nb::arg("value") = true)
.def("display_aggregates_only", &Benchmark::DisplayAggregatesOnly,
nb::rv_policy::reference, nb::arg("value") = true)
.def("measure_process_cpu_time", &Benchmark::MeasureProcessCPUTime,
nb::rv_policy::reference)
.def("use_real_time", &Benchmark::UseRealTime, nb::rv_policy::reference)
.def("use_manual_time", &Benchmark::UseManualTime,
nb::rv_policy::reference)
.def(
"complexity",
(Benchmark * (Benchmark::*)(benchmark::BigO)) & Benchmark::Complexity,
nb::rv_policy::reference, nb::arg("complexity") = benchmark::oAuto);
using benchmark::Counter;
nb::class_<Counter> py_counter(m, "Counter");
nb::enum_<Counter::Flags>(py_counter, "Flags", nb::is_arithmetic(),
nb::is_flag())
.value("kDefaults", Counter::Flags::kDefaults)
.value("kIsRate", Counter::Flags::kIsRate)
.value("kAvgThreads", Counter::Flags::kAvgThreads)
.value("kAvgThreadsRate", Counter::Flags::kAvgThreadsRate)
.value("kIsIterationInvariant", Counter::Flags::kIsIterationInvariant)
.value("kIsIterationInvariantRate",
Counter::Flags::kIsIterationInvariantRate)
.value("kAvgIterations", Counter::Flags::kAvgIterations)
.value("kAvgIterationsRate", Counter::Flags::kAvgIterationsRate)
.value("kInvert", Counter::Flags::kInvert)
.export_values();
nb::enum_<Counter::OneK>(py_counter, "OneK")
.value("kIs1000", Counter::OneK::kIs1000)
.value("kIs1024", Counter::OneK::kIs1024)
.export_values();
py_counter
.def(nb::init<double, Counter::Flags, Counter::OneK>(),
nb::arg("value") = 0., nb::arg("flags") = Counter::kDefaults,
nb::arg("k") = Counter::kIs1000)
.def("__init__",
([](Counter* c, double value) { new (c) Counter(value); }))
.def_rw("value", &Counter::value)
.def_rw("flags", &Counter::flags)
.def_rw("oneK", &Counter::oneK)
.def(nb::init_implicit<double>());
nb::implicitly_convertible<nb::int_, Counter>();
nb::bind_map<benchmark::UserCounters>(m, "UserCounters");
using benchmark::State;
nb::class_<State>(m, "State")
.def("__bool__", &State::KeepRunning)
.def_prop_ro("keep_running", &State::KeepRunning)
.def("pause_timing", &State::PauseTiming)
.def("resume_timing", &State::ResumeTiming)
.def("skip_with_error", &State::SkipWithError)
.def_prop_ro("error_occurred", &State::error_occurred)
.def("set_iteration_time", &State::SetIterationTime)
.def_prop_rw("bytes_processed", &State::bytes_processed,
&State::SetBytesProcessed)
.def_prop_rw("complexity_n", &State::complexity_length_n,
&State::SetComplexityN)
.def_prop_rw("items_processed", &State::items_processed,
&State::SetItemsProcessed)
.def("set_label", &State::SetLabel)
.def(
"range",
[](const State& state, std::size_t pos = 0) -> int64_t {
if (pos < state.range_size()) {
return state.range(pos);
}
throw nb::index_error("pos is out of range");
},
nb::arg("pos") = 0)
.def_prop_ro("iterations", &State::iterations)
.def_prop_ro("name", &State::name)
.def_rw("counters", &State::counters)
.def_prop_ro("thread_index", &State::thread_index)
.def_prop_ro("threads", &State::threads);
m.def("Initialize", Initialize);
m.def("RegisterBenchmark", RegisterBenchmark, nb::rv_policy::reference);
m.def("RunSpecifiedBenchmarks",
[]() { benchmark::RunSpecifiedBenchmarks(); });
m.def("ClearRegisteredBenchmarks", benchmark::ClearRegisteredBenchmarks);
m.def("AddCustomContext", benchmark::AddCustomContext, nb::arg("key"),
nb::arg("value"),
"Add a key-value pair to output as part of the context stanza in the "
"report.");
};
} // namespace
================================================
FILE: bindings/python/google_benchmark/example.py
================================================
# Copyright 2020 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Example of Python using C++ benchmark framework.
To run this example, you must first install the `google_benchmark` Python
package.
To install using `setup.py`, download and extract the `google_benchmark` source.
In the extracted directory, execute:
python setup.py install
"""
import random
import sys
import time
import google_benchmark as benchmark
from google_benchmark import Counter
@benchmark.register
def empty(state):
while state:
pass
@benchmark.register
def sum_million(state):
while state:
sum(range(1_000_000))
@benchmark.register
def pause_timing(state):
"""Pause timing every iteration."""
while state:
# Construct a list of random ints every iteration without timing it
state.pause_timing()
random_list = [random.randint(0, 100) for _ in range(100)]
state.resume_timing()
# Time the in place sorting algorithm
random_list.sort()
@benchmark.register
def skipped(state):
if True: # Test some predicate here.
state.skip_with_error("some error")
return # NOTE: You must explicitly return, or benchmark will continue.
# Benchmark code would be here.
@benchmark.register
@benchmark.option.use_manual_time()
def manual_timing(state):
while state:
# Manually count Python CPU time
start = time.perf_counter() # perf_counter_ns() in Python 3.7+
# Something to benchmark
time.sleep(0.01)
end = time.perf_counter()
state.set_iteration_time(end - start)
@benchmark.register
def custom_counters(state):
"""Collect custom metric using benchmark.Counter."""
num_foo = 0.0
while state:
# Benchmark some code here
# Collect some custom metric named foo
num_foo += 0.13
# Automatic Counter from numbers.
state.counters["foo"] = num_foo
# Set a counter as a rate.
state.counters["foo_rate"] = Counter(num_foo, Counter.kIsRate)
# Set a counter as an inverse of rate.
state.counters["foo_inv_rate"] = Counter(
num_foo, Counter.kIsRate | Counter.kInvert
)
# Set a counter as a thread-average quantity.
state.counters["foo_avg"] = Counter(num_foo, Counter.kAvgThreads)
# There's also a combined flag:
state.counters["foo_avg_rate"] = Counter(num_foo, Counter.kAvgThreadsRate)
@benchmark.register
@benchmark.option.measure_process_cpu_time()
@benchmark.option.use_real_time()
def with_options(state):
while state:
sum(range(1_000_000))
@benchmark.register(name="sum_million_microseconds")
@benchmark.option.unit(benchmark.kMicrosecond)
def with_options2(state):
while state:
sum(range(1_000_000))
@benchmark.register
@benchmark.option.arg(100)
@benchmark.option.arg(1000)
def passing_argument(state):
while state:
sum(range(state.range(0)))
@benchmark.register
@benchmark.option.range(8, limit=8 << 10)
def using_range(state):
while state:
sum(range(state.range(0)))
@benchmark.register
@benchmark.option.range_multiplier(2)
@benchmark.option.range(1 << 10, 1 << 18)
@benchmark.option.complexity(benchmark.oN)
def computing_complexity(state):
while state:
sum(range(state.range(0)))
state.complexity_n = state.range(0)
if __name__ == "__main__":
benchmark.add_custom_context("python", sys.version)
benchmark.main()
================================================
FILE: cmake/AddCXXCompilerFlag.cmake
================================================
# - Adds a compiler flag if it is supported by the compiler
#
# This function checks that the supplied compiler flag is supported and then
# adds it to the corresponding compiler flags
#
# add_cxx_compiler_flag(<FLAG> [<VARIANT>])
#
# - Example
#
# include(AddCXXCompilerFlag)
# add_cxx_compiler_flag(-Wall)
# add_cxx_compiler_flag(-no-strict-aliasing RELEASE)
# Requires CMake 2.6+
if(__add_cxx_compiler_flag)
return()
endif()
set(__add_cxx_compiler_flag INCLUDED)
include(CheckCXXCompilerFlag)
function(mangle_compiler_flag FLAG OUTPUT)
string(TOUPPER "HAVE_CXX_FLAG_${FLAG}" SANITIZED_FLAG)
string(REPLACE "+" "X" SANITIZED_FLAG ${SANITIZED_FLAG})
string(REGEX REPLACE "[^A-Za-z_0-9]" "_" SANITIZED_FLAG ${SANITIZED_FLAG})
string(REGEX REPLACE "_+" "_" SANITIZED_FLAG ${SANITIZED_FLAG})
set(${OUTPUT} "${SANITIZED_FLAG}" PARENT_SCOPE)
endfunction(mangle_compiler_flag)
function(add_cxx_compiler_flag FLAG)
mangle_compiler_flag("${FLAG}" MANGLED_FLAG)
set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}")
check_cxx_compiler_flag("${FLAG}" ${MANGLED_FLAG})
set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
if(${MANGLED_FLAG})
if(ARGC GREATER 1)
set(VARIANT ${ARGV1})
string(TOUPPER "_${VARIANT}" VARIANT)
else()
set(VARIANT "")
endif()
set(CMAKE_CXX_FLAGS${VARIANT} "${CMAKE_CXX_FLAGS${VARIANT}} ${BENCHMARK_CXX_FLAGS${VARIANT}} ${FLAG}" PARENT_SCOPE)
endif()
endfunction()
function(add_required_cxx_compiler_flag FLAG)
mangle_compiler_flag("${FLAG}" MANGLED_FLAG)
set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}")
check_cxx_compiler_flag("${FLAG}" ${MANGLED_FLAG})
set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
if(${MANGLED_FLAG})
if(ARGC GREATER 1)
set(VARIANT ${ARGV1})
string(TOUPPER "_${VARIANT}" VARIANT)
else()
set(VARIANT "")
endif()
set(CMAKE_CXX_FLAGS${VARIANT} "${CMAKE_CXX_FLAGS${VARIANT}} ${FLAG}" PARENT_SCOPE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE)
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAG}" PARENT_SCOPE)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${FLAG}" PARENT_SCOPE)
else()
message(FATAL_ERROR "Required flag '${FLAG}' is not supported by the compiler")
endif()
endfunction()
function(check_cxx_warning_flag FLAG)
mangle_compiler_flag("${FLAG}" MANGLED_FLAG)
set(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
# Add -Werror to ensure the compiler generates an error if the warning flag
# doesn't exist.
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror ${FLAG}")
check_cxx_compiler_flag("${FLAG}" ${MANGLED_FLAG})
set(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
endfunction()
================================================
FILE: cmake/CXXFeatureCheck.cmake
================================================
# - Compile and run code to check for C++ features
#
# This functions compiles a source file under the `cmake` folder
# and adds the corresponding `HAVE_[FILENAME]` flag to the CMake
# environment
#
# cxx_feature_check(<FLAG> [<VARIANT>])
#
# - Example
#
# include(CXXFeatureCheck)
# cxx_feature_check(STD_REGEX)
# Requires CMake 2.8.12+
if(__cxx_feature_check)
return()
endif()
set(__cxx_feature_check INCLUDED)
option(CXXFEATURECHECK_DEBUG OFF)
function(cxx_feature_check FILE)
string(TOLOWER ${FILE} FILE)
string(TOUPPER ${FILE} VAR)
string(TOUPPER "HAVE_${VAR}" FEATURE)
if (DEFINED HAVE_${VAR})
if(HAVE_${VAR})
add_definitions(-DHAVE_${VAR})
endif()
return()
endif()
set(FEATURE_CHECK_CMAKE_FLAGS ${BENCHMARK_CXX_LINKER_FLAGS})
if (ARGC GREATER 1)
message(STATUS "Enabling additional flags: ${ARGV1}")
list(APPEND FEATURE_CHECK_CMAKE_FLAGS ${ARGV1})
endif()
if (NOT DEFINED COMPILE_${FEATURE})
if(CMAKE_CROSSCOMPILING)
message(STATUS "Cross-compiling to test ${FEATURE}")
try_compile(COMPILE_${FEATURE}
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}
LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}
OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)
if(COMPILE_${FEATURE})
message(WARNING
"If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0")
set(RUN_${FEATURE} 0 CACHE INTERNAL "")
else()
set(RUN_${FEATURE} 1 CACHE INTERNAL "")
endif()
else()
message(STATUS "Compiling and running to test ${FEATURE}")
try_run(RUN_${FEATURE} COMPILE_${FEATURE}
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}
LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}
COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)
endif()
endif()
if(COMPILE_${FEATURE})
if(DEFINED RUN_${FEATURE} AND RUN_${FEATURE} EQUAL 0)
message(STATUS "Performing Test ${FEATURE} -- success")
set(HAVE_${VAR} 1 CACHE INTERNAL "")
add_definitions(-DHAVE_${VAR})
else()
message(STATUS "Performing Test ${FEATURE} -- compiled but failed to run")
set(HAVE_${VAR} 0 CACHE INTERNAL "")
endif()
else()
if(CXXFEATURECHECK_DEBUG)
message(STATUS "Performing Test ${FEATURE} -- failed to compile: ${COMPILE_OUTPUT_VAR}")
else()
message(STATUS "Performing Test ${FEATURE} -- failed to compile")
endif()
set(HAVE_${VAR} 0 CACHE INTERNAL "")
endif()
endfunction()
================================================
FILE: cmake/Config.cmake.in
================================================
@PACKAGE_INIT@
include (CMakeFindDependencyMacro)
find_dependency (Threads)
if (@BENCHMARK_ENABLE_LIBPFM@)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
find_dependency (PFM)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake")
================================================
FILE: cmake/GetGitVersion.cmake
================================================
# - Returns a version string from Git tags
#
# This function inspects the annotated git tags for the project and returns a string
# into a CMake variable
#
# get_git_version(<var>)
#
# - Example
#
# include(GetGitVersion)
# get_git_version(GIT_VERSION)
#
# Requires CMake 2.8.11+
find_package(Git)
if(__get_git_version)
return()
endif()
set(__get_git_version INCLUDED)
function(get_git_version var)
if(GIT_EXECUTABLE)
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --match "v[0-9]*.[0-9]*.[0-9]*" --abbrev=8 --dirty
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE status
OUTPUT_VARIABLE GIT_VERSION
ERROR_QUIET)
if(status)
set(GIT_VERSION "v0.0.0")
endif()
else()
set(GIT_VERSION "v0.0.0")
endif()
set(${var} ${GIT_VERSION} PARENT_SCOPE)
endfunction()
================================================
FILE: cmake/GoogleTest.cmake
================================================
# Download and unpack googletest at configure time
set(GOOGLETEST_PREFIX "${benchmark_BINARY_DIR}/third_party/googletest")
configure_file(${benchmark_SOURCE_DIR}/cmake/GoogleTest.cmake.in ${GOOGLETEST_PREFIX}/CMakeLists.txt @ONLY)
set(GOOGLETEST_PATH "${CMAKE_CURRENT_SOURCE_DIR}/googletest" CACHE PATH "") # Mind the quotes
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
-DALLOW_DOWNLOADING_GOOGLETEST=${BENCHMARK_DOWNLOAD_DEPENDENCIES} -DGOOGLETEST_PATH:PATH=${GOOGLETEST_PATH} .
RESULT_VARIABLE result
WORKING_DIRECTORY ${GOOGLETEST_PREFIX}
)
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${GOOGLETEST_PREFIX}
)
if(result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
# Prevent overriding the parent project's compiler/linker
# settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
include(${GOOGLETEST_PREFIX}/googletest-paths.cmake)
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${GOOGLETEST_SOURCE_DIR}
${GOOGLETEST_BINARY_DIR}
EXCLUDE_FROM_ALL)
# googletest doesn't seem to want to stay build warning clean so let's not hurt ourselves.
if (MSVC)
target_compile_options(gtest PRIVATE "/wd4244" "/wd4722")
target_compile_options(gtest_main PRIVATE "/wd4244" "/wd4722")
target_compile_options(gmock PRIVATE "/wd4244" "/wd4722")
target_compile_options(gmock_main PRIVATE "/wd4244" "/wd4722")
else()
target_compile_options(gtest PRIVATE "-w")
target_compile_options(gtest_main PRIVATE "-w")
target_compile_options(gmock PRIVATE "-w")
target_compile_options(gmock_main PRIVATE "-w")
endif()
if(NOT DEFINED GTEST_COMPILE_COMMANDS)
set(GTEST_COMPILE_COMMANDS ON)
endif()
set_target_properties(gtest PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gtest,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})
set_target_properties(gtest_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gtest_main,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})
set_target_properties(gmock PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gmock,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})
set_target_properties(gmock_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gmock_main,INTERFACE_INCLUDE_DIRECTORIES> EXPORT_COMPILE_COMMANDS ${GTEST_COMPILE_COMMANDS})
================================================
FILE: cmake/GoogleTest.cmake.in
================================================
cmake_minimum_required (VERSION 3.13...3.22)
project(googletest-download NONE)
# Enable ExternalProject CMake module
include(ExternalProject)
option(ALLOW_DOWNLOADING_GOOGLETEST "If googletest src tree is not found in location specified by GOOGLETEST_PATH, do fetch the archive from internet" OFF)
set(GOOGLETEST_PATH "/usr/src/googletest" CACHE PATH
"Path to the googletest root tree. Should contain googletest and googlemock subdirs. And CMakeLists.txt in root, and in both of these subdirs")
# Download and install GoogleTest
message(STATUS "Looking for Google Test sources")
message(STATUS "Looking for Google Test sources in ${GOOGLETEST_PATH}")
if(EXISTS "${GOOGLETEST_PATH}" AND IS_DIRECTORY "${GOOGLETEST_PATH}" AND EXISTS "${GOOGLETEST_PATH}/CMakeLists.txt" AND
EXISTS "${GOOGLETEST_PATH}/googletest" AND IS_DIRECTORY "${GOOGLETEST_PATH}/googletest" AND EXISTS "${GOOGLETEST_PATH}/googletest/CMakeLists.txt" AND
EXISTS "${GOOGLETEST_PATH}/googlemock" AND IS_DIRECTORY "${GOOGLETEST_PATH}/googlemock" AND EXISTS "${GOOGLETEST_PATH}/googlemock/CMakeLists.txt")
message(STATUS "Found Google Test in ${GOOGLETEST_PATH}")
ExternalProject_Add(
googletest
PREFIX "${CMAKE_BINARY_DIR}"
DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/download"
SOURCE_DIR "${GOOGLETEST_PATH}" # use existing src dir.
BINARY_DIR "${CMAKE_BINARY_DIR}/build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
else()
if(NOT ALLOW_DOWNLOADING_GOOGLETEST)
message(SEND_ERROR "Did not find Google Test sources! Either pass correct path in GOOGLETEST_PATH, or enable BENCHMARK_DOWNLOAD_DEPENDENCIES, or disable BENCHMARK_USE_BUNDLED_GTEST, or disable BENCHMARK_ENABLE_GTEST_TESTS / BENCHMARK_ENABLE_TESTING.")
return()
else()
message(STATUS "Did not find Google Test sources! Fetching from web...")
ExternalProject_Add(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG "v1.15.2"
GIT_SHALLOW "ON"
PREFIX "${CMAKE_BINARY_DIR}"
STAMP_DIR "${CMAKE_BINARY_DIR}/stamp"
DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/download"
SOURCE_DIR "${CMAKE_BINARY_DIR}/src"
BINARY_DIR "${CMAKE_BINARY_DIR}/build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
endif()
endif()
ExternalProject_Get_Property(googletest SOURCE_DIR BINARY_DIR)
file(WRITE googletest-paths.cmake
"set(GOOGLETEST_SOURCE_DIR \"${SOURCE_DIR}\")
set(GOOGLETEST_BINARY_DIR \"${BINARY_DIR}\")
")
================================================
FILE: cmake/benchmark.pc.in
================================================
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
Name: @PROJECT_NAME@
Description: Google microbenchmark framework
Version: @NORMALIZED_VERSION@
Libs: -L${libdir} -lbenchmark
Libs.private: -lpthread @BENCHMARK_PRIVATE_LINK_LIBRARIES@
Cflags: -I${includedir}
================================================
FILE: cmake/benchmark_main.pc.in
================================================
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
Name: @PROJECT_NAME@
Description: Google microbenchmark framework (with main() function)
Version: @NORMALIZED_VERSION@
Requires: benchmark
Libs: -L${libdir} -lbenchmark_main
================================================
FILE: cmake/gnu_posix_regex.cpp
================================================
#include <gnuregex.h>
#include <string>
int main() {
std::string str = "test0159";
regex_t re;
int ec = regcomp(&re, "^[a-z]+[0-9]+$", REG_EXTENDED | REG_NOSUB);
if (ec != 0) {
return ec;
}
return regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0;
}
================================================
FILE: cmake/llvm-toolchain.cmake
================================================
find_package(LLVMAr REQUIRED)
set(CMAKE_AR "${LLVMAR_EXECUTABLE}" CACHE FILEPATH "" FORCE)
find_package(LLVMNm REQUIRED)
set(CMAKE_NM "${LLVMNM_EXECUTABLE}" CACHE FILEPATH "" FORCE)
find_package(LLVMRanLib REQUIRED)
set(CMAKE_RANLIB "${LLVMRANLIB_EXECUTABLE}" CACHE FILEPATH "" FORCE)
================================================
FILE: cmake/posix_regex.cpp
================================================
#include <regex.h>
#include <string>
int main() {
std::string str = "test0159";
regex_t re;
int ec = regcomp(&re, "^[a-z]+[0-9]+$", REG_EXTENDED | REG_NOSUB);
if (ec != 0) {
return ec;
}
int ret = regexec(&re, str.c_str(), 0, nullptr, 0) ? -1 : 0;
regfree(&re);
return ret;
}
================================================
FILE: cmake/pthread_affinity.cpp
================================================
#include <pthread.h>
#ifdef __FreeBSD__
#include <pthread_np.h>
#endif
int main() {
cpu_set_t set;
CPU_ZERO(&set);
for (int i = 0; i < CPU_SETSIZE; ++i) {
CPU_SET(i, &set);
CPU_CLR(i, &set);
}
pthread_t self = pthread_self();
int ret;
ret = pthread_getaffinity_np(self, sizeof(set), &set);
if (ret != 0) return ret;
ret = pthread_setaffinity_np(self, sizeof(set), &set);
if (ret != 0) return ret;
return 0;
}
================================================
FILE: cmake/split_list.cmake
================================================
macro(split_list listname)
string(REPLACE ";" " " ${listname} "${${listname}}")
endmacro()
================================================
FILE: cmake/std_regex.cpp
================================================
#include <regex>
#include <string>
int main() {
const std::string str = "test0159";
std::regex re;
re = std::regex("^[a-z]+[0-9]+$",
std::regex_constants::extended | std::regex_constants::nosubs);
return std::regex_search(str, re) ? 0 : -1;
}
================================================
FILE: cmake/steady_clock.cpp
================================================
#include <chrono>
int main() {
typedef std::chrono::steady_clock Clock;
Clock::time_point tp = Clock::now();
((void)tp);
}
================================================
FILE: cmake/thread_safety_attributes.cpp
================================================
#define HAVE_THREAD_SAFETY_ATTRIBUTES
#include "../src/mutex.h"
int main() {}
================================================
FILE: docs/AssemblyTests.md
================================================
# Assembly Tests
The Benchmark library provides a number of functions whose primary
purpose in to affect assembly generation, including `DoNotOptimize`
and `ClobberMemory`. In addition there are other functions,
such as `KeepRunning`, for which generating good assembly is paramount.
For these functions it's important to have tests that verify the
correctness and quality of the implementation. This requires testing
the code generated by the compiler.
This document describes how the Benchmark library tests compiler output,
as well as how to properly write new tests.
## Anatomy of a Test
Writing a test has two steps:
* Write the code you want to generate assembly for.
* Add `// CHECK` lines to match against the verified assembly.
Example:
```c++
// CHECK-LABEL: test_add:
extern "C" int test_add() {
extern int ExternInt;
return ExternInt + 1;
// CHECK: movl ExternInt(%rip), %eax
// CHECK: addl %eax
// CHECK: ret
}
```
#### LLVM Filecheck
[LLVM's Filecheck](https://llvm.org/docs/CommandGuide/FileCheck.html)
is used to test the generated assembly against the `// CHECK` lines
specified in the tests source file. Please see the documentation
linked above for information on how to write `CHECK` directives.
#### Tips and Tricks:
* Tests should match the minimal amount of output required to establish
correctness. `CHECK` directives don't have to match on the exact next line
after the previous match, so tests should omit checks for unimportant
bits of assembly. ([`CHECK-NEXT`](https://llvm.org/docs/CommandGuide/FileCheck.html#the-check-next-directive)
can be used to ensure a match occurs exactly after the previous match).
* The tests are compiled with `-O3 -g0`. So we're only testing the
optimized output.
* The assembly output is further cleaned up using `tools/strip_asm.py`.
This removes comments, assembler directives, and unused labels before
the test is run.
* The generated and stripped assembly file for a test is output under
`<build-directory>/test/<test-name>.s`
* Filecheck supports using [`CHECK` prefixes](https://llvm.org/docs/CommandGuide/FileCheck.html#cmdoption-check-prefixes)
to specify lines that should only match in certain situations.
The Benchmark tests use `CHECK-CLANG` and `CHECK-GNU` for lines that
are only expected to match Clang or GCC's output respectively. Normal
`CHECK` lines match against all compilers. (Note: `CHECK-NOT` and
`CHECK-LABEL` are NOT prefixes. They are versions of non-prefixed
`CHECK` lines)
* Use `extern "C"` to disable name mangling for specific functions. This
makes them easier to name in the `CHECK` lines.
## Problems Writing Portable Tests
Writing tests which check the code generated by a compiler are
inherently non-portable. Different compilers and even different compiler
versions may generate entirely different code. The Benchmark tests
must tolerate this.
LLVM Filecheck provides a number of mechanisms to help write
"more portable" tests; including [matching using regular expressions](https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-pattern-matching-syntax),
allowing the creation of [named variables](https://llvm.org/docs/CommandGuide/FileCheck.html#filecheck-variables)
for later matching, and [checking non-sequential matches](https://llvm.org/docs/CommandGuide/FileCheck.html#the-check-dag-directive).
#### Capturing Variables
For example, say GCC stores a variable in a register but Clang stores
it in memory. To write a test that tolerates both cases we "capture"
the destination of the store, and then use the captured expression
to write the remainder of the test.
```c++
// CHECK-LABEL: test_div_no_op_into_shr:
extern "C" void test_div_no_op_into_shr(int value) {
int divisor = 2;
benchmark::DoNotOptimize(divisor); // hide the value from the optimizer
return value / divisor;
// CHECK: movl $2, [[DEST:.*]]
// CHECK: idivl [[DEST]]
// CHECK: ret
}
```
#### Using Regular Expressions to Match Differing Output
Often tests require testing assembly lines which may subtly differ
between compilers or compiler versions. A common example of this
is matching stack frame addresses. In this case regular expressions
can be used to match the differing bits of output. For example:
<!-- {% raw %} -->
```c++
int ExternInt;
struct Point { int x, y, z; };
// CHECK-LABEL: test_store_point:
extern "C" void test_store_point() {
Point p{ExternInt, ExternInt, ExternInt};
benchmark::DoNotOptimize(p);
// CHECK: movl ExternInt(%rip), %eax
// CHECK: movl %eax, -{{[0-9]+}}(%rsp)
// CHECK: movl %eax, -{{[0-9]+}}(%rsp)
// CHECK: movl %eax, -{{[0-9]+}}(%rsp)
// CHECK: ret
}
```
<!-- {% endraw %} -->
## Current Requirements and Limitations
The tests require Filecheck to be installed along the `PATH` of the
build machine. Otherwise the tests will be disabled.
Additionally, as mentioned in the previous section, codegen tests are
inherently non-portable. Currently the tests are limited to:
* x86_64 targets.
* Compiled with GCC or Clang
Further work could be done, at least on a limited basis, to extend the
tests to other architectures and compilers (using `CHECK` prefixes).
Furthermore, the tests fail for builds which specify additional flags
that modify code generation, including `--coverage` or `-fsanitize=`.
================================================
FILE: docs/_config.yml
================================================
theme: jekyll-theme-minimal
logo: /assets/images/icon_black.png
show_downloads: true
================================================
FILE: docs/dependencies.md
================================================
# Build tool dependency policy
We follow the [Foundational C++ support policy](https://opensource.google/documentation/policies/cplusplus-support) for our build tools. In
particular the ["Build Systems" section](https://opensource.google/documentation/policies/cplusplus-support#build-systems).
## CMake
The current supported version is CMake 3.10 as of 2023-08-10. Most modern
distributions include newer versions, for example:
* Ubuntu 20.04 provides CMake 3.16.3
* Debian 11.4 provides CMake 3.18.4
* Ubuntu 22.04 provides CMake 3.22.1
## Python
The Python bindings require Python 3.10+ as of v1.9.0 (2024-08-16) for installation from PyPI.
Building from source for older versions probably still works, though. See the [user guide](python_bindings.md) for details on how to build from source.
The minimum theoretically supported version is Python 3.8, since the used bindings generator (nanobind) only supports Python 3.8+.
================================================
FILE: docs/index.md
================================================
# Benchmark
* [Assembly Tests](AssemblyTests.md)
* [Dependencies](dependencies.md)
* [Perf Counters](perf_counters.md)
* [Platform Specific Build Instructions](platform_specific_build_instructions.md)
* [Python Bindings](python_bindings.md)
* [Random Interleaving](random_interleaving.md)
* [Reducing Variance](reducing_variance.md)
* [Releasing](releasing.md)
* [Tools](tools.md)
* [User Guide](user_guide.md)
================================================
FILE: docs/perf_counters.md
================================================
<a name="perf-counters" />
# User-Requested Performance Counters
When running benchmarks, the user may choose to request collection of
performance counters. This may be useful in investigation scenarios - narrowing
down the cause of a regression; or verifying that the underlying cause of a
performance improvement matches expectations.
This feature is available if:
* The benchmark is run on an architecture featuring a Performance Monitoring
Unit (PMU),
* The benchmark is compiled with support for collecting counters. Currently,
this requires [libpfm](http://perfmon2.sourceforge.net/), which is built as a
dependency via Bazel.
The feature does not require modifying benchmark code. Counter collection is
handled at the boundaries where timer collection is also handled.
To opt-in:
* If using a Bazel build, add `--define pfm=1` to your build flags
* If using CMake:
* Install `libpfm4-dev`, e.g. `apt-get install libpfm4-dev`.
* Enable the CMake flag `BENCHMARK_ENABLE_LIBPFM` in `CMakeLists.txt`.
To use, pass a comma-separated list of counter names through the
`--benchmark_perf_counters` flag. The names are decoded through libpfm - meaning,
they are platform specific, but some (e.g. `CYCLES` or `INSTRUCTIONS`) are
mapped by libpfm to platform-specifics - see libpfm
[documentation](http://perfmon2.sourceforge.net/docs.html) for more details.
The counter values are reported back through the [User Counters](../README.md#custom-counters)
mechanism, meaning, they are available in all the formats (e.g. JSON) supported
by User Counters.
================================================
FILE: docs/platform_specific_build_instructions.md
================================================
# Platform Specific Build Instructions
## Building with GCC
When the library is built using GCC it is necessary to link with the pthread
library due to how GCC implements `std::thread`. Failing to link to pthread will
lead to runtime exceptions (unless you're using libc++), not linker errors. See
[issue #67](https://github.com/google/benchmark/issues/67) for more details. You
can link to pthread by adding `-pthread` to your linker command. Note, you can
also use `-lpthread`, but there are potential issues with ordering of command
line parameters if you use that.
On QNX, the pthread library is part of libc and usually included automatically
(see
[`pthread_create()`](https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.lib_ref/topic/p/pthread_create.html)).
There's no separate pthread library to link.
## Building with Visual Studio 2015, 2017 or 2022
The `shlwapi` library (`-lshlwapi`) is required to support a call to `CPUInfo` which reads the registry. Either add `shlwapi.lib` under `[ Configuration Properties > Linker > Input ]`, or use the following:
```
// Alternatively, can add libraries using linker options.
// First, Add the path to the generated library files (directory containing the `benchmark.lib`) in `[Configuration Properties > Linker > General > Additional Library Directories]`. Then do the following:
#ifdef _WIN32
#pragma comment ( lib, "Shlwapi.lib" )
#ifdef _DEBUG
#pragma comment ( lib, "benchmark.lib" )
#else
#pragma comment ( lib, "benchmark.lib" )
#endif
#endif
```
When using the static library, make sure to add `BENCHMARK_STATIC_DEFINE` under `[Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions]`
Can also use the graphical version of CMake:
* Open `CMake GUI`.
* Under `Where to build the binaries`, same path as source plus `build`.
* Under `CMAKE_INSTALL_PREFIX`, same path as source plus `install`.
* Click `Configure`, `Generate`, `Open Project`.
* If build fails, try deleting entire directory and starting again, or unticking options to build less.
## Building with Intel 2015 Update 1 or Intel System Studio Update 4
See instructions for building with Visual Studio. Once built, right click on the solution and change the build to Intel.
## Building on Solaris
If you're running benchmarks on solaris, you'll want the kstat library linked in
too (`-lkstat`).
================================================
FILE: docs/python_bindings.md
================================================
# Building and installing Python bindings
Python bindings are available as wheels on [PyPI](https://pypi.org/project/google-benchmark/) for importing and
using Google Benchmark directly in Python.
Currently, pre-built wheels exist for macOS (both ARM64 and Intel x86), Linux x86-64 and 64-bit Windows.
Supported Python versions are Python 3.8 - 3.12.
To install Google Benchmark's Python bindings, run:
```bash
python -m pip install --upgrade pip # for manylinux2014 support
python -m pip install google-benchmark
```
In order to keep your system Python interpreter clean, it is advisable to run these commands in a virtual
environment. See the [official Python documentation](https://docs.python.org/3/library/venv.html)
on how to create virtual environments.
To build a wheel directly from source, you can follow these steps:
```bash
git clone https://github.com/google/benchmark.git
cd benchmark
# create a virtual environment and activate it
python3 -m venv venv --system-site-packages
source venv/bin/activate # .\venv\Scripts\Activate.ps1 on Windows
# upgrade Python's system-wide packages
python -m pip install --upgrade pip build
# builds the wheel and stores it in the directory "dist".
python -m build
```
NB: Building wheels from source requires Bazel. For platform-specific instructions on how to install Bazel,
refer to the [Bazel installation docs](https://bazel.build/install).
================================================
FILE: docs/random_interleaving.md
================================================
<a name="interleaving" />
# Random Interleaving
[Random Interleaving](https://github.com/google/benchmark/issues/1051) is a
technique to lower run-to-run variance. It randomly interleaves repetitions of a
microbenchmark with repetitions from other microbenchmarks in the same benchmark
test. Data shows it is able to lower run-to-run variance by
[40%](https://github.com/google/benchmark/issues/1051) on average.
To use, you mainly need to set `--benchmark_enable_random_interleaving=true`,
and optionally specify non-zero repetition count `--benchmark_repetitions=9`
and optionally decrease the per-repetition time `--benchmark_min_time=0.1`.
================================================
FILE: docs/reducing_variance.md
================================================
# Reducing Variance
<a name="disabling-cpu-frequency-scaling" />
## Disabling CPU Frequency Scaling
If you see this error:
```
***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead.
```
you might want to disable the CPU frequency scaling while running the
benchmark, as well as consider other ways to stabilize the performance of
your system while benchmarking.
Exactly how to do this depends on the Linux distribution,
desktop environment, and installed programs. Specific details are a moving
target, so we will not attempt to exhaustively document them here.
One simple option is to use the `cpupower` program to change the
performance governor to "performance". This tool is maintained along with
the Linux kernel and provided by your distribution.
It must be run as root, like this:
```bash
sudo cpupower frequency-set --governor performance
```
After this you can verify that all CPUs are using the performance governor
by running this command:
```bash
cpupower frequency-info -o proc
```
The benchmarks you subsequently run will have less variance.
<a name="reducing-variance" />
## Disabling ASLR
If you see this error:
```
***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.
```
you might want to disable the ASLR security hardening feature while running the
benchmark.
The simplest way is to add
```
benchmark::MaybeReenterWithoutASLR(argc, argv);
```
as the first line of your `main()` function. It will try to disable ASLR
for the current processor, and, if successful, re-execute the binary.
Note that `personality(2)` may be forbidden by e.g. seccomp (which happens
by default if you are running in a Docker container).
Note that if you link to `benchmark_main` already does that for you.
To globally disable ASLR on Linux, run
```
echo 0 > /proc/sys/kernel/randomize_va_space
```
To run a single benchmark with ASLR disabled on Linux, do:
```
setarch `uname -m` -R ./a_benchmark
```
Note that for the information on how to disable ASLR on other operating systems,
please refer to their documentation.
## Reducing Variance in Benchmarks
The Linux CPU frequency governor [discussed
above](user_guide#disabling-cpu-frequency-scaling) is not the only source
of noise in benchmarks. Some, but not all, of the sources of variance
include:
1. On multi-core machines not all CPUs/CPU cores/CPU threads run the same
speed, so running a benchmark one time and then again may give a
different result depending on which CPU it ran on.
2. CPU scaling features that run on the CPU, like Intel's Turbo Boost and
AMD Turbo Core and Precision Boost, can temporarily change the CPU
frequency even when the using the "performance" governor on Linux.
3. Context switching between CPUs, or scheduling competition on the CPU the
benchmark is running on.
4. Intel Hyperthreading or AMD SMT causing the same issue as above.
5. Cache effects caused by code running on other CPUs.
6. Non-uniform memory architectures (NUMA).
These can cause variance in benchmarks results within a single run
(`--benchmark_repetitions=N`) or across multiple runs of the benchmark
program.
Reducing sources of variance is OS and architecture dependent, which is one
reason some companies maintain machines dedicated to performance testing.
Some of the easier and effective ways of reducing variance on a typical
Linux workstation are:
1. Use the performance governor as [discussed
above](user_guide#disabling-cpu-frequency-scaling).
2. Disable processor boosting by:
```sh
echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost
```
See the Linux kernel's
[boost.txt](https://www.kernel.org/doc/Documentation/cpu-freq/boost.txt)
for more information.
3. Set the benchmark program's task affinity to a fixed cpu. For example:
```sh
taskset -c 0 ./mybenchmark
```
4. Increase the program's scheduling priority to minimize context switches using `nice` or `chrt`:
```sh
sudo nice -n -20 ./mybenchmark
sudo chrt -f 80 ./mybenchmark
```
5. Disabling Hyperthreading/SMT. This can be done in the Bios or using the
`/sys` file system (see the LLVM project's [Benchmarking
tips](https://llvm.org/docs/Benchmarking.html)).
6. Close other programs that do non-trivial things based on timers, such as
your web browser, desktop environment, etc.
7. Reduce the working set of your benchmark to fit within the L1 cache, but
do be aware that this may lead you to optimize for an unrealistic
situation.
Further resources on this topic:
1. The LLVM project's [Benchmarking
tips](https://llvm.org/docs/Benchmarking.html).
1. The Arch Wiki [Cpu frequency
scaling](https://wiki.archlinux.org/title/CPU_frequency_scaling) page.
================================================
FILE: docs/releasing.md
================================================
# How to release
* Make sure you're on main and synced to HEAD
* Ensure the project builds and tests run
* `parallel -j0 exec ::: test/*_test` can help ensure everything at least
passes
* Prepare release notes
* `git log $(git describe --abbrev=0 --tags)..HEAD` gives you the list of
commits between the last annotated tag and HEAD
* Pick the most interesting.
* Create one last commit that updates the version saved in `CMakeLists.txt`, `MODULE.bazel`,
and `bindings/python/google_benchmark/__init__.py` to the release version you're creating.
(This version will be used if benchmark is installed from the archive you'll be creating
in the next step.)
```
# CMakeLists.txt
project (benchmark VERSION 1.9.0 LANGUAGES CXX)
```
```
# MODULE.bazel
module(name = "com_github_google_benchmark", version="1.9.0")
```
```
# google_benchmark/__init__.py
__version__ = "1.9.0"
```
* Create a release through github's interface
* Note this will create a lightweight tag.
* Update this to an annotated tag:
* `git pull --tags`
* `git tag -a -f <tag> <tag>`
* `git push --force --tags origin`
* Confirm that the "Build and upload Python wheels" action runs to completion
* Run it manually if it hasn't run.
================================================
FILE: docs/tools.md
================================================
# Benchmark Tools
## compare.py
The `compare.py` can be used to compare the result of benchmarks.
### Dependencies
The utility relies on the [scipy](https://www.scipy.org) package which can be installed using pip:
```bash
pip3 install -r requirements.txt
```
### Displaying aggregates only
The switch `-a` / `--display_aggregates_only` can be used to control the
displayment of the normal iterations vs the aggregates. When passed, it will
be passthrough to the benchmark binaries to be run, and will be accounted for
in the tool itself; only the aggregates will be displayed, but not normal runs.
It only affects the display, the separate runs will still be used to calculate
the U test.
### Modes of operation
There are three modes of operation:
1. Just compare two benchmarks
The program is invoked like:
``` bash
$ compare.py benchmarks <benchmark_baseline> <benchmark_contender> [benchmark options]...
```
Where `<benchmark_baseline>` and `<benchmark_contender>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
Example output:
```
$ ./compare.py benchmarks ./a.out ./a.out
RUNNING: ./a.out --benchmark_out=/tmp/tmprBT5nW
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:16:44
------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------
BM_memcpy/8 36 ns 36 ns 19101577 211.669MB/s
BM_memcpy/64 76 ns 76 ns 9412571 800.199MB/s
BM_memcpy/512 84 ns 84 ns 8249070 5.64771GB/s
BM_memcpy/1024 116 ns 116 ns 6181763 8.19505GB/s
BM_memcpy/8192 643 ns 643 ns 1062855 11.8636GB/s
BM_copy/8 222 ns 222 ns 3137987 34.3772MB/s
BM_copy/64 1608 ns 1608 ns 432758 37.9501MB/s
BM_copy/512 12589 ns 12589 ns 54806 38.7867MB/s
BM_copy/1024 25169 ns 25169 ns 27713 38.8003MB/s
BM_copy/8192 201165 ns 201112 ns 3486 38.8466MB/s
RUNNING: ./a.out --benchmark_out=/tmp/tmpt1wwG_
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:16:53
------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------
BM_memcpy/8 36 ns 36 ns 19397903 211.255MB/s
BM_memcpy/64 73 ns 73 ns 9691174 839.635MB/s
BM_memcpy/512 85 ns 85 ns 8312329 5.60101GB/s
BM_memcpy/1024 118 ns 118 ns 6438774 8.11608GB/s
BM_memcpy/8192 656 ns 656 ns 1068644 11.6277GB/s
BM_copy/8 223 ns 223 ns 3146977 34.2338MB/s
BM_copy/64 1611 ns 1611 ns 435340 37.8751MB/s
BM_copy/512 12622 ns 12622 ns 54818 38.6844MB/s
BM_copy/1024 25257 ns 25239 ns 27779 38.6927MB/s
BM_copy/8192 205013 ns 205010 ns 3479 38.108MB/s
Comparing ./a.out to ./a.out
Benchmark Time CPU Time Old Time New CPU Old CPU New
------------------------------------------------------------------------------------------------------
BM_memcpy/8 +0.0020 +0.0020 36 36 36 36
BM_memcpy/64 -0.0468 -0.0470 76 73 76 73
BM_memcpy/512 +0.0081 +0.0083 84 85 84 85
BM_memcpy/1024 +0.0098 +0.0097 116 118 116 118
BM_memcpy/8192 +0.0200 +0.0203 643 656 643 656
BM_copy/8 +0.0046 +0.0042 222 223 222 223
BM_copy/64 +0.0020 +0.0020 1608 1611 1608 1611
BM_copy/512 +0.0027 +0.0026 12589 12622 12589 12622
BM_copy/1024 +0.0035 +0.0028 25169 25257 25169 25239
BM_copy/8192 +0.0191 +0.0194 201165 205013 201112 205010
```
What it does is for the every benchmark from the first run it looks for the benchmark with exactly the same name in the second run, and then compares the results. If the names differ, the benchmark is omitted from the diff.
As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
2. Compare two different filters of one benchmark
The program is invoked like:
``` bash
$ compare.py filters <benchmark> <filter_baseline> <filter_contender> [benchmark options]...
```
Where `<benchmark>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
Where `<filter_baseline>` and `<filter_contender>` are the same regex filters that you would pass to the `[--benchmark_filter=<regex>]` parameter of the benchmark binary.
`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
Example output:
```
$ ./compare.py filters ./a.out BM_memcpy BM_copy
RUNNING: ./a.out --benchmark_filter=BM_memcpy --benchmark_out=/tmp/tmpBWKk0k
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:37:28
------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------
BM_memcpy/8 36 ns 36 ns 17891491 211.215MB/s
BM_memcpy/64 74 ns 74 ns 9400999 825.646MB/s
BM_memcpy/512 87 ns 87 ns 8027453 5.46126GB/s
BM_memcpy/1024 111 ns 111 ns 6116853 8.5648GB/s
BM_memcpy/8192 657 ns 656 ns 1064679 11.6247GB/s
RUNNING: ./a.out --benchmark_filter=BM_copy --benchmark_out=/tmp/tmpAvWcOM
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:37:33
----------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------
BM_copy/8 227 ns 227 ns 3038700 33.6264MB/s
BM_copy/64 1640 ns 1640 ns 426893 37.2154MB/s
BM_copy/512 12804 ns 12801 ns 55417 38.1444MB/s
BM_copy/1024 25409 ns 25407 ns 27516 38.4365MB/s
BM_copy/8192 202986 ns 202990 ns 3454 38.4871MB/s
Comparing BM_memcpy to BM_copy (from ./a.out)
Benchmark Time CPU Time Old Time New CPU Old CPU New
--------------------------------------------------------------------------------------------------------------------
[BM_memcpy vs. BM_copy]/8 +5.2829 +5.2812 36 227 36 227
[BM_memcpy vs. BM_copy]/64 +21.1719 +21.1856 74 1640 74 1640
[BM_memcpy vs. BM_copy]/512 +145.6487 +145.6097 87 12804 87 12801
[BM_memcpy vs. BM_copy]/1024 +227.1860 +227.1776 111 25409 111 25407
[BM_memcpy vs. BM_copy]/8192 +308.1664 +308.2898 657 202986 656 202990
```
As you can see, it applies filter to the benchmarks, both when running the benchmark, and before doing the diff. And to make the diff work, the matches are replaced with some common string. Thus, you can compare two different benchmark families within one benchmark binary.
As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
3. Compare filter one from benchmark one to filter two from benchmark two:
The program is invoked like:
``` bash
$ compare.py filters <benchmark_baseline> <filter_baseline> <benchmark_contender> <filter_contender> [benchmark options]...
```
Where `<benchmark_baseline>` and `<benchmark_contender>` either specify a benchmark executable file, or a JSON output file. The type of the input file is automatically detected. If a benchmark executable is specified then the benchmark is run to obtain the results. Otherwise the results are simply loaded from the output file.
Where `<filter_baseline>` and `<filter_contender>` are the same regex filters that you would pass to the `[--benchmark_filter=<regex>]` parameter of the benchmark binary.
`[benchmark options]` will be passed to the benchmarks invocations. They can be anything that binary accepts, be it either normal `--benchmark_*` parameters, or some custom parameters your binary takes.
Example output:
```
$ ./compare.py benchmarksfiltered ./a.out BM_memcpy ./a.out BM_copy
RUNNING: ./a.out --benchmark_filter=BM_memcpy --benchmark_out=/tmp/tmp_FvbYg
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:38:27
------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------
BM_memcpy/8 37 ns 37 ns 18953482 204.118MB/s
BM_memcpy/64 74 ns 74 ns 9206578 828.245MB/s
BM_memcpy/512 91 ns 91 ns 8086195 5.25476GB/s
BM_memcpy/1024 120 ns 120 ns 5804513 7.95662GB/s
BM_memcpy/8192 664 ns 664 ns 1028363 11.4948GB/s
RUNNING: ./a.out --benchmark_filter=BM_copy --benchmark_out=/tmp/tmpDfL5iE
Run on (8 X 4000 MHz CPU s)
2017-11-07 21:38:32
----------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------
BM_copy/8 230 ns 230 ns 2985909 33.1161MB/s
BM_copy/64 1654 ns 1653 ns 419408 36.9137MB/s
BM_copy/512 13122 ns 13120 ns 53403 37.2156MB/s
BM_copy/1024 26679 ns 26666 ns 26575 36.6218MB/s
BM_copy/8192 215068 ns 215053 ns 3221 36.3283MB/s
Comparing BM_memcpy (from ./a.out) to BM_copy (from ./a.out)
Benchmark Time CPU Time Old Time New CPU Old CPU New
--------------------------------------------------------------------------------------------------------------------
[BM_memcpy vs. BM_copy]/8 +5.1649 +5.1637 37 230 37 230
[BM_memcpy vs. BM_copy]/64 +21.4352 +21.4374 74 1654 74 1653
[BM_memcpy vs. BM_copy]/512 +143.6022 +143.5865 91 13122 91 13120
[BM_memcpy vs. BM_copy]/1024 +221.5903 +221.4790 120 26679 120 26666
[BM_memcpy vs. BM_copy]/8192 +322.9059 +323.0096 664 215068 664 215053
```
This is a mix of the previous two modes, two (potentially different) benchmark binaries are run, and a different filter is applied to each one.
As you can note, the values in `Time` and `CPU` columns are calculated as `(new - old) / |old|`.
### Note: Interpreting the output
Performance measurements are an art, and performance comparisons are doubly so.
Results are often noisy and don't necessarily have large absolute differences to
them, so just by visual inspection, it is not at all apparent if two
measurements are actually showing a performance change or not. It is even more
confusing with multiple benchmark repetitions.
Thankfully, what we can do, is use statistical tests on the results to determine
whether the performance has statistically-significantly changed. `compare.py`
uses [Mann–Whitney U
test](https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test), with a null
hypothesis being that there's no difference in performance.
**The below output is a summary of a benchmark comparison with statistics
provided for a multi-threaded process.**
```
Benchmark Time CPU Time Old Time New CPU Old CPU New
-----------------------------------------------------------------------------------------------------------------------------
benchmark/threads:1/process_time/real_time_pvalue 0.0000 0.0000 U Test, Repetitions: 27 vs 27
benchmark/threads:1/process_time/real_time_mean -0.1442 -0.1442 90 77 90 77
benchmark/threads:1/process_time/real_time_median -0.1444 -0.1444 90 77 90 77
benchmark/threads:1/process_time/real_time_stddev +0.3974 +0.3933 0 0 0 0
benchmark/threads:1/process_time/real_time_cv +0.6329 +0.6280 0 0 0 0
OVERALL_GEOMEAN -0.1442 -0.1442 0 0 0 0
```
--------------------------------------------
Here's a breakdown of each row:
**benchmark/threads:1/process_time/real_time_pvalue**: This shows the _p-value_ for
the statistical test comparing the performance of the process running with one
thread. A value of 0.0000 suggests a statistically significant difference in
performance. The comparison was conducted using the U Test (Mann-Whitney
U Test) with 27 repetitions for each case.
**benchmark/threads:1/process_time/real_time_mean**: This shows the relative
difference in mean execution time between two different cases. The negative
value (-0.1442) implies that the new process is faster by about 14.42%. The old
time was 90 units, while the new time is 77 units.
**benchmark/threads:1/process_time/real_time_median**: Similarly, this shows the
relative difference in the median execution time. Again, the new process is
faster by 14.44%.
**benchmark/threads:1/process_time/real_time_stddev**: This is the relative
difference in the standard deviation of the execution time, which is a measure
of how much variation or dispersion there is from the mean. A positive value
(+0.3974) implies there is more variance in the execution time in the new
process.
**benchmark/threads:1/process_time/real_time_cv**: CV stands for Coefficient of
Variation. It is the ratio of the standard deviation to the mean. It provides a
standardized measure of dispersion. An increase (+0.6329) indicates more
relative variability in the new process.
**OVERALL_GEOMEAN**: Geomean stands for geometric mean, a type of average that is
less influenced by outliers. The negative value indicates a general improvement
in the new process. However, given the values are all zero for the old and new
times, this seems to be a mistake or placeholder in the output.
-----------------------------------------
Let's first try to see what the different columns represent in the above
`compare.py` benchmarking output:
1. **Benchmark:** The name of the function being benchmarked, along with the
size of the input (after the slash).
2. **Time:** The average time per operation, across all iterations.
3. **CPU:** The average CPU time per operation, across all iterations.
4. **Iterations:** The number of iterations the benchmark was run to get a
stable estimate.
5. **Time Old and Time New:** These represent the average time it takes for a
function to run in two different scenarios or versions. For example, you
might be comparing how fast a function runs before and after you make some
changes to it.
6. **CPU Old and CPU New:** These show the average amount of CPU time that the
function uses in two different scenarios or versions. This is similar to
Time Old and Time New, but focuses on CPU usage instead of overall time.
In the comparison section, the relative differences in both time and CPU time
are displayed for each input size.
A statistically-significant difference is determined by a **p-value**, which is
a measure of the probability that the observed difference could have occurred
just by random chance. A smaller p-value indicates stronger evidence against the
null hypothesis.
**Therefore:**
1. If the p-value is less than the chosen significance level (alpha), we
reject the null hypothesis and conclude the benchmarks are significantly
different.
2. If the p-value is greater than or equal to alpha, we fail to reject the
null hypothesis and treat the two benchmarks as similar.
The result of said the statistical test is additionally communicated through color coding:
```diff
+ Green:
```
The benchmarks are _**statistically different**_. This could mean the
performance has either **significantly improved** or **significantly
deteriorated**. You should look at the actual performance numbers to see which
is the case.
```diff
- Red:
```
The benchmarks are _**statistically similar**_. This means the performance
**hasn't significantly changed**.
In statistical terms, **'green'** means we reject the null hypothesis that
there's no difference in performance, and **'red'** means we fail to reject the
null hypothesis. This might seem counter-intuitive if you're expecting 'green'
to mean 'improved performance' and 'red' to mean 'worsened performance'.
```bash
But remember, in this context:
'Success' means 'successfully finding a difference'.
'Failure' means 'failing to find a difference'.
```
Also, please note that **even if** we determine that there **is** a
statistically-significant difference between the two measurements, it does not
_necessarily_ mean that the actual benchmarks that were measured **are**
different, or vice versa, even if we determine that there is **no**
statistically-significant difference between the two measurements, it does not
necessarily mean that the actual benchmarks that were measured **are not**
different.
### U test
If there is a sufficient repetition count of the benchmarks, the tool can do
a [U Test](https://en.wikipedia.org/wiki/Mann%E2%80%93Whitney_U_test), of the
null hypothesis that it is equally likely that a randomly selected value from
one sample will be less than or greater than a randomly selected value from a
second sample.
If the calculated p-value is below this value is lower than the significance
level alpha, then the result is said to be statistically significant and the
null hypothesis is rejected. Which in other words means that the two benchmarks
aren't identical.
**WARNING**: requires **LARGE** (no less than 9) number of repetitions to be
meaningful!
================================================
FILE: docs/user_guide.md
================================================
# User Guide
## Command Line
[Output Formats](#output-formats)
[Output Files](#output-files)
[Running Benchmarks](#running-benchmarks)
[Running a Subset of Benchmarks](#running-a-subset-of-benchmarks)
[Result Comparison](#result-comparison)
[Extra Context](#extra-context)
## Library
[Runtime and Reporting Considerations](#runtime-and-reporting-considerations)
[Setup/Teardown](#setupteardown)
[Passing Arguments](#passing-arguments)
[Custom Benchmark Name](#custom-benchmark-name)
[Calculating Asymptotic Complexity](#asymptotic-complexity)
[Templated Benchmarks](#templated-benchmarks)
[Templated Benchmarks that take arguments](#templated-benchmarks-with-arguments)
[Fixtures](#fixtures)
[Custom Counters](#custom-counters)
[Multithreaded Benchmarks](#multithreaded-benchmarks)
[CPU Timers](#cpu-timers)
[Manual Timing](#manual-timing)
[Setting the Time Unit](#setting-the-time-unit)
[Random Interleaving](random_interleaving.md)
[User-Requested Performance Counters](perf_counters.md)
[Preventing Optimization](#preventing-optimization)
[Reporting Statistics](#reporting-statistics)
[Custom Statistics](#custom-statistics)
[Memory Usage](#memory-usage)
[Using RegisterBenchmark](#using-register-benchmark)
[Exiting with an Error](#exiting-with-an-error)
[A Faster `KeepRunning` Loop](#a-faster-keep-running-loop)
## Benchmarking Tips
[Disabling CPU Frequency Scaling](#disabling-cpu-frequency-scaling)
[Reducing Variance in Benchmarks](reducing_variance.md)
<a name="output-formats" />
## Output Formats
The library supports multiple output formats. Use the
`--benchmark_format=<console|json|csv>` flag (or set the
`BENCHMARK_FORMAT=<console|json|csv>` environment variable) to set
the format type. `console` is the default format.
The Console format is intended to be a human readable format. By default
the format generates color output. Context is output on stderr and the
tabular data on stdout. Example tabular output looks like:
```
Benchmark Time(ns) CPU(ns) Iterations
----------------------------------------------------------------------
BM_SetInsert/1024/1 28928 29349 23853 133.097kiB/s 33.2742k items/s
BM_SetInsert/1024/8 32065 32913 21375 949.487kiB/s 237.372k items/s
BM_SetInsert/1024/10 33157 33648 21431 1.13369MiB/s 290.225k items/s
```
The JSON format outputs human readable json split into two top level attributes.
The `context` attribute contains information about the run in general, including
information about the CPU and the date.
The `benchmarks` attribute contains a list of every benchmark run. Example json
output looks like:
```json
{
"context": {
"date": "2015/03/17-18:40:25",
"num_cpus": 40,
"mhz_per_cpu": 2801,
"cpu_scaling_enabled": false,
"build_type": "debug"
},
"benchmarks": [
{
"name": "BM_SetInsert/1024/1",
"iterations": 94877,
"real_time": 29275,
"cpu_time": 29836,
"bytes_per_second": 134066,
"items_per_second": 33516
},
{
"name": "BM_SetInsert/1024/8",
"iterations": 21609,
"real_time": 32317,
"cpu_time": 32429,
"bytes_per_second": 986770,
"items_per_second": 246693
},
{
"name": "BM_SetInsert/1024/10",
"iterations": 21393,
"real_time": 32724,
"cpu_time": 33355,
"bytes_per_second": 1199226,
"items_per_second": 299807
}
]
}
```
The CSV format outputs comma-separated values. The `context` is output on stderr
and the CSV itself on stdout. Example CSV output looks like:
```
name,iterations,real_time,cpu_time,bytes_per_second,items_per_second,label
"BM_SetInsert/1024/1",65465,17890.7,8407.45,475768,118942,
"BM_SetInsert/1024/8",116606,18810.1,9766.64,3.27646e+06,819115,
"BM_SetInsert/1024/10",106365,17238.4,8421.53,4.74973e+06,1.18743e+06,
```
<a name="output-files" />
## Output Files
Write benchmark results to a file with the `--benchmark_out=<filename>` option
(or set `BENCHMARK_OUT`). Specify the output format with
`--benchmark_out_format={json|console|csv}` (or set
`BENCHMARK_OUT_FORMAT={json|console|csv}`). Note that the 'csv' reporter is
deprecated and the saved `.csv` file
[is not parsable](https://github.com/google/benchmark/issues/794) by csv
parsers.
Specifying `--benchmark_out` does not suppress the console output.
<a name="running-benchmarks" />
## Running Benchmarks
Benchmarks are executed by running the produced binaries. Benchmarks binaries,
by default, accept options that may be specified either through their command
line interface or by setting environment variables before execution. For every
`--option_flag=<value>` CLI switch, a corresponding environment variable
`OPTION_FLAG=<value>` exist and is used as default if set (CLI switches always
prevails). A complete list of CLI options is available running benchmarks
with the `--help` switch.
### Dry runs
To confirm that benchmarks can run successfully without needing to wait for
multiple repetitions and iterations, the `--benchmark_dry_run` flag can be
used. This will run the benchmarks as normal, but for 1 iteration and 1
repetition only.
<a name="running-a-subset-of-benchmarks" />
## Running a Subset of Benchmarks
The `--benchmark_filter=<regex>` option (or `BENCHMARK_FILTER=<regex>`
environment variable) can be used to only run the benchmarks that match
the specified `<regex>`. For example:
```bash
$ ./run_benchmarks.x --benchmark_filter=BM_memcpy/32
Run on (1 X 2300 MHz CPU )
2016-06-25 19:34:24
Benchmark Time CPU Iterations
----------------------------------------------------
BM_memcpy/32 11 ns 11 ns 79545455
BM_memcpy/32k 2181 ns 2185 ns 324074
BM_memcpy/32 12 ns 12 ns 54687500
BM_memcpy/32k 1834 ns 1837 ns 357143
```
## Disabling Benchmarks
It is possible to temporarily disable benchmarks by renaming the benchmark
function to have the prefix "DISABLED_". This will cause the benchmark to
be skipped at runtime.
<a name="result-comparison" />
## Result comparison
It is possible to compare the benchmarking results.
See [Additional Tooling Documentation](tools.md)
<a name="extra-context" />
## Extra Context
Sometimes it's useful to add extra context to the content printed before the
results. By default this section includes information about the CPU on which
the benchmarks are running. If you do want to add more context, you can use
the `benchmark_context` command line flag:
```bash
$ ./run_benchmarks --benchmark_context=pwd=`pwd`
Run on (1 x 2300 MHz CPU)
pwd: /home/user/benchmark/
Benchmark Time CPU Iterations
----------------------------------------------------
BM_memcpy/32 11 ns 11 ns 79545455
BM_memcpy/32k 2181 ns 2185 ns 324074
```
You can get the same effect with the API:
```c++
benchmark::AddCustomContext("foo", "bar");
```
Note that attempts to add a second value with the same key will fail with an
error message.
<a name="runtime-and-reporting-considerations" />
## Runtime and Reporting Considerations
When the benchmark binary is executed, each benchmark function is run serially.
The number of iterations to run is determined dynamically by running the
benchmark a few times and measuring the time taken and ensuring that the
ultimate result will be statistically stable. As such, faster benchmark
functions will be run for more iterations than slower benchmark functions, and
the number of iterations is thus reported.
In all cases, the number of iterations for which the benchmark is run is
governed by the amount of time the benchmark takes. Concretely, the number of
iterations is at least one, not more than 1e9, until CPU time is greater than
the minimum time, or the wallclock time is 5x minimum time. The minimum time is
set per benchmark by calling `MinTime` on the registered benchmark object.
Furthermore warming up a benchmark might be necessary in order to get
stable results because of e.g caching effects of the code under benchmark.
Warming up means running the benchmark a given amount of time, before
results are actually taken into account. The amount of time for which
the warmup should be run can be set per benchmark by calling
`MinWarmUpTime` on the registered benchmark object or for all benchmarks
using the `--benchmark_min_warmup_time` command-line option. Note that
`MinWarmUpTime` will overwrite the value of `--benchmark_min_warmup_time`
for the single benchmark. How many iterations the warmup run of each
benchmark takes is determined the same way as described in the paragraph
above. Per default the warmup phase is set to 0 seconds and is therefore
disabled.
Average timings are then reported over the iterations run. If multiple
repetitions are requested using the `--benchmark_repetitions` command-line
option, or at registration time, the benchmark function will be run several
times and statistical results across these repetitions will also be reported.
As well as the per-benchmark entries, a preamble in the report will include
information about the machine on which the benchmarks are run.
<a name="setup-teardown" />
## Setup/Teardown
Global setup/teardown specific to each benchmark can be done by
passing a callback to Setup/Teardown:
The setup/teardown callbacks will be invoked once for each benchmark. If the
benchmark is multi-threaded (will run in k threads), they will be invoked
exactly once before each run with k threads.
If the benchmark uses different size groups of threads, the above will be true
for each size group.
Eg.,
```c++
static void DoSetup(const benchmark::State& state) {
}
static void DoTeardown(const benchmark::State& state) {
}
static void BM_func(benchmark::State& state) {...}
BENCHMARK(BM_func)->Arg(1)->Arg(3)->Threads(16)->Threads(32)->Setup(DoSetup)->Teardown(DoTeardown);
```
In this example, `DoSetup` and `DoTearDown` will be invoked 4 times each,
specifically, once for each of this family:
- BM_func_Arg_1_Threads_16, BM_func_Arg_1_Threads_32
- BM_func_Arg_3_Threads_16, BM_func_Arg_3_Threads_32
<a name="passing-arguments" />
## Passing Arguments
Sometimes a family of benchmarks can be implemented with just one routine that
takes an extra argument to specify which one of the family of benchmarks to
run. For example, the following code defines a family of benchmarks for
measuring the speed of `memcpy()` calls of different lengths:
```c++
static void BM_memcpy(benchmark::State& state) {
char* src = new char[state.range(0)];
char* dst = new char[state.range(0)];
memset(src, 'x', state.range(0));
for (auto _ : state)
memcpy(dst, src, state.range(0));
state.SetBytesProcessed(int64_t(state.iterations()) *
int64_t(state.range(0)));
delete[] src;
delete[] dst;
}
BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(4<<10)->Arg(8<<10);
```
The preceding code is quite repetitive, and can be replaced with the following
short-hand. The following invocation will pick a few appropriate arguments in
the specified range and will generate a benchmark for each such argument.
```c++
BENCHMARK(BM_memcpy)->Range(8, 8<<10);
```
By default the arguments in the range are generated in multiples of eight and
the command above selects [ 8, 64, 512, 4k, 8k ]. In the following code the
range multiplier is changed to multiples of two.
```c++
BENCHMARK(BM_memcpy)->RangeMultiplier(2)->Range(8, 8<<10);
```
Now arguments generated are [ 8, 16, 32, 64, 128, 256, 512, 1024, 2k, 4k, 8k ].
The preceding code shows a method of defining a sparse range. The following
example shows a method of defining a dense range. It is then used to benchmark
the performance of `std::vector` initialization for uniformly increasing sizes.
```c++
static void BM_DenseRange(benchmark::State& state) {
for(auto _ : state) {
std::vector<int> v(state.range(0), state.range(0));
auto data = v.data();
benchmark::DoNotOptimize(data);
benchmark::ClobberMemory();
}
}
BENCHMARK(BM_DenseRange)->DenseRange(0, 1024, 128);
```
Now arguments generated are [ 0, 128, 256, 384, 512, 640, 768, 896, 1024 ].
You might have a benchmark that depends on two or more inputs. For example, the
following code defines a family of benchmarks for measuring the speed of set
insertion.
```c++
static void BM_SetInsert(benchmark::State& state) {
std::set<int> data;
for (auto _ : state) {
state.PauseTiming();
data = ConstructRandomSet(state.range(0));
state.ResumeTiming();
for (int j = 0; j < state.range(1); ++j)
data.insert(RandomNumber());
}
}
BENCHMARK(BM_SetInsert)
->Args({1<<10, 128})
->Args({2<<10, 128})
->Args({4<<10, 128})
->Args({8<<10, 128})
->Args({1<<10, 512})
->Args({2<<10, 512})
->Args({4<<10, 512})
->Args({8<<10, 512});
```
The preceding code is quite repetitive, and can be replaced with the following
short-hand. The following macro will pick a few appropriate arguments in the
product of the two specified ranges and will generate a benchmark for each such
pair.
<!-- {% raw %} -->
```c++
BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});
```
<!-- {% endraw %} -->
Some benchmarks may require specific argument values that cannot be expressed
with `Ranges`. In this case, `ArgsProduct` offers the ability to generate a
benchmark input for each combination in the product of the supplied vectors.
<!-- {% raw %} -->
```c++
BENCHMARK(BM_SetInsert)
->ArgsProduct({{1<<10, 3<<10, 8<<10}, {20, 40, 60, 80}})
// would generate the same benchmark arguments as
BENCHMARK(BM_SetInsert)
->Args({1<<10, 20})
->Args({3<<10, 20})
->Args({8<<10, 20})
->Args({3<<10, 40})
->Args({8<<10, 40})
->Args({1<<10, 40})
->Args({1<<10, 60})
->Args({3<<10, 60})
->Args({8<<10, 60})
->Args({1<<10, 80})
->Args({3<<10, 80})
->Args({8<<10, 80});
```
<!-- {% endraw %} -->
For the most common scenarios, helper methods for creating a list of
integers for a given sparse or dense range are provided.
```c++
BENCHMARK(BM_SetInsert)
->ArgsProduct({
benchmark::CreateRange(8, 128, /*multi=*/2),
benchmark::CreateDenseRange(1, 4, /*step=*/1)
})
// would generate the same benchmark arguments as
BENCHMARK(BM_SetInsert)
->ArgsProduct({
{8, 16, 32, 64, 128},
{1, 2, 3, 4}
});
```
For more complex patterns of inputs, passing a custom function to `Apply` allows
programmatic specification of an arbitrary set of arguments on which to run the
benchmark. The following example enumerates a dense range on one parameter,
and a sparse range on the second.
```c++
static void CustomArguments(benchmark::Benchmark* b) {
for (int i = 0; i <= 10; ++i)
for (int j = 32; j <= 1024*1024; j *= 8)
b->Args({i, j});
}
BENCHMARK(BM_SetInsert)->Apply(CustomArguments);
```
### Passing Arbitrary Arguments to a Benchmark
It is possible to define a benchmark that takes an arbitrary number
of extra arguments. The `BENCHMARK_CAPTURE(func, test_case_name, ...args)`
macro creates a benchmark that invokes `func` with the `benchmark::State` as
the first argument followed by the specified `args...`.
The `test_case_name` is appended to the name of the benchmark and
should describe the values passed.
```c++
template <class ...Args>
void BM_takes_args(benchmark::State& state, Args&&... args) {
auto args_tuple = std::make_tuple(std::move(args)...);
for (auto _ : state) {
std::cout << std::get<0>(args_tuple) << ": " << std::get<1>(args_tuple)
<< '\n';
[...]
}
}
// Registers a benchmark named "BM_takes_args/int_string_test" that passes
// the specified values to `args`.
BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc"));
// Registers the same benchmark "BM_takes_args/int_test" that passes
// the specified values to `args`.
BENCHMARK_CAPTURE(BM_takes_args, int_test, 42, 43);
```
Note that elements of `...args` may refer to global variables. Users should
avoid modifying global state inside of a benchmark.
### Naming a Benchmark Without Capturing Arguments
If you only need to give a benchmark a custom name (without passing extra
arguments), use `BENCHMARK_NAMED(func, test_case_name)`. Unlike
`BENCHMARK_CAPTURE`, this macro does not create a lambda, which avoids
compiler and linker scalability issues when registering thousands of
benchmarks.
```c++
void BM_Foo(benchmark::State& state) {
for (auto _ : state) {}
}
// Registers a benchmark named "BM_Foo/my_variant"
BENCHMARK_NAMED(BM_Foo, my_variant);
```
Use `BENCHMARK_CAPTURE` when you need to pass extra arguments; use
`BENCHMARK_NAMED` when you only need the name.
<a name="asymptotic-complexity" />
## Calculating Asymptotic Complexity (Big O)
Asymptotic complexity might be calculated for a family of benchmarks. The
following code will calculate the coefficient for the high-order term in the
running time and the normalized root-mean square error of string comparison.
```c++
static void BM_StringCompare(benchmark::State& state) {
std::string s1(state.range(0), '-');
std::string s2(state.range(0), '-');
for (auto _ : state) {
auto comparison_result = s1.compare(s2);
benchmark::DoNotOptimize(comparison_result);
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_StringCompare)
->RangeMultiplier(2)->Range(1<<10, 1<<18)->Complexity(benchmark::oN);
```
As shown in the following invocation, asymptotic complexity might also be
calculated automatically.
```c++
BENCHMARK(BM_StringCompare)
->RangeMultiplier(2)->Range(1<<10, 1<<18)->Complexity();
```
The following code will specify asymptotic complexity with a lambda function,
that might be used to customize high-order term calculation.
```c++
BENCHMARK(BM_StringCompare)->RangeMultiplier(2)
->Range(1<<10, 1<<18)->Complexity([](benchmark::IterationCount n)->double{return n; });
```
<a name="custom-benchmark-name" />
## Custom Benchmark Name
You can change the benchmark's name as follows:
```c++
BENCHMARK(BM_memcpy)->Name("memcpy")->RangeMultiplier(2)->Range(8, 8<<10);
```
The invocation will execute the benchmark as before using `BM_memcpy` but changes
the prefix in the report to `memcpy`.
<a name="templated-benchmarks" />
## Templated Benchmarks
This example produces and consumes messages of size `sizeof(v)` `range_x`
times. It also outputs throughput in the absence of multiprogramming.
```c++
template <class Q> void BM_Sequential(benchmark::State& state) {
Q q;
typename Q::value_type v;
for (auto _ : state) {
for (int i = state.range(0); i--; )
q.push(v);
for (int e = state.range(0); e--; )
q.Wait(&v);
}
// actually messages, not bytes:
state.SetBytesProcessed(
static_cast<int64_t>(state.iterations())*state.range(0));
}
// You can use the BENCHMARK macro with template parameters:
BENCHMARK(BM_Sequential<WaitQueue<int>>)->Range(1<<0, 1<<10);
// Old, legacy verbose C++03 syntax:
BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);
```
Three macros are provided for adding benchmark templates.
```c++
#define BENCHMARK(func<...>) // Takes any number of parameters.
#define BENCHMARK_TEMPLATE1(func, arg1)
#define BENCHMARK_TEMPLATE2(func, arg1, arg2)
```
<a name="templated-benchmarks-with-arguments" />
## Templated Benchmarks that take arguments
Sometimes there is a need to template benchmarks, and provide arguments to them.
```c++
template <class Q> void BM_Sequential_With_Step(benchmark::State& state, int step) {
Q q;
typename Q::value_type v;
for (auto _ : state) {
for (int i = state.range(0); i-=step; )
q.push(v);
for (int e = state.range(0); e-=step; )
q.Wait(&v);
}
// actually messages, not bytes:
state.SetBytesProcessed(
static_cast<int64_t>(state.iterations())*state.range(0));
}
BENCHMARK_TEMPLATE1_CAPTURE(BM_Sequential, WaitQueue<int>, Step1, 1)->Range(1<<0, 1<<10);
```
<a name="fixtures" />
## Fixtures
Fixture tests are created by first defining a type that derives from
`::benchmark::Fixture` and then creating/registering the tests using the
following macros:
* `BENCHMARK_F(ClassName, Method)`
* `BENCHMARK_DEFINE_F(ClassName, Method)`
* `BENCHMARK_REGISTER_F(ClassName, Method)`
For Example:
```c++
class MyFixture : public benchmark::Fixture {
public:
void SetUp(::benchmark::State& state) {
}
void TearDown(::benchmark::State& state) {
}
};
// Defines and registers `FooTest` using the class `MyFixture`.
BENCHMARK_F(MyFixture, FooTest)(benchmark::State& st) {
for (auto _ : st) {
...
}
}
// Only defines `BarTest` using the class `MyFixture`.
BENCHMARK_DEFINE_F(MyFixture, BarTest)(benchmark::State& st) {
for (auto _ : st) {
...
}
}
// `BarTest` is NOT registered.
BENCHMARK_REGISTER_F(MyFixture, BarTest)->Threads(2);
// `BarTest` is now registered.
```
### Templated Fixtures
Also you can create templated fixture by using the following macros:
* `BENCHMARK_TEMPLATE_F(ClassName, Method, ...)`
* `BENCHMARK_TEMPLATE_DEFINE_F(ClassName, Method, ...)`
For example:
```c++
template<typename T>
class MyFixture : public benchmark::Fixture {};
// Defines and registers `IntTest` using the class template `MyFixture<int>`.
BENCHMARK_TEMPLATE_F(MyFixture, IntTest, int)(benchmark::State& st) {
for (auto _ : st) {
...
}
}
// Only defines `DoubleTest` using the class template `MyFixture<double>`.
BENCHMARK_TEMPLATE_DEFINE_F(MyFixture, DoubleTest, double)(benchmark::State& st) {
for (auto _ : st) {
...
}
}
// `DoubleTest` is NOT registered.
BENCHMARK_REGISTER_F(MyFixture, DoubleTest)->Threads(2);
// `DoubleTest` is now registered.
```
If you want to use a method template for your fixtures,
which you instantiate afterward, use the following macros:
* `BENCHMARK_TEMPLATE_METHOD_F(ClassName, Method)`
* `BENCHMARK_TEMPLATE_INSTANTIATE_F(ClassName, Method, ...)`
With these macros you can define one method for several instantiations.
Example (using `MyFixture` from above):
```c++
// Defines `Test` using the class template `MyFixture`.
BENCHMARK_TEMPLATE_METHOD_F(MyFixture, Test)(benchmark::State& st) {
for (auto _ : st) {
...
}
}
// Instantiates and registers the benchmark `MyFixture<int>::Test`.
BENCHMARK_TEMPLATE_INSTANTIATE_F(MyFixture, Test, int)->Threads(2);
// Instantiates and registers the benchmark `MyFixture<double>::Test`.
BENCHMARK_TEMPLATE_INSTANTIATE_F(MyFixture, Test, double)->Threads(4);
```
Inside the method definition of `BENCHMARK_TEMPLATE_METHOD_F` the type `Base` refers
to the type of the instantiated fixture.
Accesses to members of the fixture must be prefixed by `this->`.
`BENCHMARK_TEMPLATE_METHOD_F`and `BENCHMARK_TEMPLATE_INSTANTIATE_F` can only be used,
if the fixture does not use non-type template parameters.
If you want to pass values as template parameters, use e.g. `std::integral_constant`.
For example:
```c++
template<typename Sz>
class SizedFixture : public benchmark::Fixture {
static constexpr auto Size = Sz::value;
int myValue;
};
BENCHMARK_TEMPLATE_METHOD_F(SizedFixture, Test)(benchmark::State& st) {
for (auto _ : st) {
this->myValue = Base::Size;
}
}
BENCHMARK_TEMPLATE_INSTANTIATE_F(SizedFixture, Test, std::integral_constant<5>)->Threads(2);
```
<a name="custom-counters" />
## Custom Counters
You can add your own counters with user-defined names. The example below
will add columns "Foo", "Bar" and "Baz" in its output:
```c++
static void UserCountersExample1(benchmark::State& state) {
double numFoos = 0, numBars = 0, numBazs = 0;
for (auto _ : state) {
// ... count Foo,Bar,Baz events
}
state.counters["Foo"] = numFoos;
state.counters["Bar"] = numBars;
state.counters["Baz"] = numBazs;
}
```
The `state.counters` object is a `std::map` with `std::string` keys
and `Counter` values. The latter is a `double`-like class, via an implicit
conversion to `double&`. Thus you can use all of the standard arithmetic
assignment operators (`=,+=,-=,*=,/=`) to change the value of each counter.
The `Counter` constructor accepts three parameters: the value as a `double`
; a bit flag which allows you to show counters as rates, and/or as per-thread
iteration, and/or as per-thread averages, and/or iteration invariants,
and/or finally inverting the result; and a flag specifying the 'unit' - i.e.
is 1k a 1000 (default, `benchmark::Counter::OneK::kIs1000`), or 1024
(`benchmark::Counter::OneK::kIs1024`)?
```c++
// sets a simple counter
state.counters["Foo"] = numFoos;
// Set the counter as a rate. It will be presented divided
// by the duration of the benchmark.
// Meaning: per one second, how many 'foo's are processed?
state.counters["FooRate"] = Counter(numFoos, benchmark::Counter::kIsRate);
// Set the counter as a rate. It will be presented divided
// by the duration of the benchmark, and the result inverted.
// Meaning: how many seconds it takes to process one 'foo'?
state.counters["FooInvRate"] = Counter(numFoos, benchmark::Counter::kIsRate | benchmark::Counter::kInvert);
// Set the counter as a thread-average quantity. It will
// be presented divided by the number of threads.
state.counters["FooAvg"] = Counter(numFoos, benchmark::Counter::kAvgThreads);
// There's also a combined flag:
state.counters["FooAvgRate"] = Counter(numFoos,benchmark::Counter::kAvgThreadsRate);
// This says that we process with the rate of state.range(0) bytes every iteration:
state.counters["BytesProcessed"] = Counter(state.range(0), benchmark::Counter::kIsIterationInvariantRate, benchmark::Counter::OneK::kIs1024);
```
You can use `insert()` with `std::initializer_list`:
<!-- {% raw %} -->
```c++
state.counters.insert({{"Foo", numFoos}, {"Bar", numBars}, {"Baz", numBazs}});
// ... instead of:
state.counters["Foo"] = numFoos;
state.counters["Bar"] = numBars;
state.counters["Baz"] = numBazs;
```
<!-- {% endraw %} -->
In multithreaded benchmarks, each counter is set on the calling thread only.
When the benchmark finishes, the counters from each thread will be summed.
Counters that are configured with `kIsRate`, will report the average rate across all threads, while `kAvgThreadsRate` counters will report the average rate per thread.
### Counter Reporting
When using the console reporter, by default, user counters are printed at
the end after the table, the same way as ``bytes_processed`` and
``items_processed``. This is best for cases in which there are few counters,
or where there are only a couple of lines per benchmark. Here's an example of
the default output:
```
------------------------------------------------------------------------------
Benchmark Time CPU Iterations UserCounters...
------------------------------------------------------------------------------
BM_UserCounter/threads:8 2248 ns 10277 ns 68808 Bar=16 Bat=40 Baz=24 Foo=8
BM_UserCounter/threads:1 9797 ns 9788 ns 71523 Bar=2 Bat=5 Baz=3 Foo=1024m
BM_UserCounter/threads:2 4924 ns 9842 ns 71036 Bar=4 Bat=10 Baz=6 Foo=2
BM_UserCounter/threads:4 2589 ns 10284 ns 68012 Bar=8 Bat=20 Baz=12 Foo=4
BM_UserCounter/threads:8 2212 ns 10287 ns 68040 Bar=16 Bat=40 Baz=24 Foo=8
BM_UserCounter/threads:16 1782 ns 10278 ns 68144 Bar=32 Bat=80 Baz=48 Foo=16
BM_UserCounter/threads:32 1291 ns 10296 ns 68256 Bar=64 Bat=160 Baz=96 Foo=32
BM_UserCounter/threads:4 2615 ns 10307 ns 68040 Bar=8 Bat=20 Baz=12 Foo=4
BM_Factorial 26 ns 26 ns 26608979 40320
BM_Factorial/real_time 26 ns 26 ns 26587936 40320
BM_CalculatePiRange/1 16 ns 16 ns 45704255 0
BM_CalculatePiRange/8 73 ns 73 ns 9520927 3.28374
BM_CalculatePiRange/64 609 ns 609 ns 1140647 3.15746
BM_CalculatePiRange/512 4900 ns 4901 ns 142696 3.14355
```
If this doesn't suit you, you can print each counter as a table column by
passing the flag `--benchmark_counters_tabular=true` to the benchmark
application. This is best for cases in which there are a lot of counters, or
a lot of lines per individual benchmark. Note that this will trigger a
reprinting of the table header any time the counter set changes between
individual benchmarks. Here's an example of corresponding output when
`--benchmark_counters_tabular=true` is passed:
```
---------------------------------------------------------------------------------------
Benchmark Time CPU Iterations Bar Bat Baz Foo
---------------------------------------------------------------------------------------
BM_UserCounter/threads:8 2198 ns 9953 ns 70688 16 40 24 8
BM_UserCounter/threads:1 9504 ns 9504 ns 73787 2 5 3 1
BM_UserCounter/threads:2 4775 ns 9550 ns 72606 4 10 6 2
BM_UserCounter/threads:4 2508 ns 9951 ns 70332 8 20 12 4
BM_UserCounter/threads:8 2055 ns 9933 ns 70344 16 40 24 8
BM_UserCounter/threads:16 1610 ns 9946 ns 70720 32 80 48 16
BM_UserCounter/threads:32 1192 ns 9948 ns 70496 64 160 96 32
BM_UserCounter/threads:4 2506 ns 9949 ns 70332 8 20 12 4
--------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------
BM_Factorial 26 ns 26 ns 26392245 40320
BM_Factorial/real_time 26 ns 26 ns 26494107 40320
BM_CalculatePiRange/1 15 ns 15 ns 45571597 0
BM_CalculatePiRange/8 74 ns 74 ns 9450212 3.28374
BM_CalculatePiRange/64 595 ns 595 ns 1173901 3.15746
BM_CalculatePiRange/512 4752 ns 4752 ns 147380 3.14355
BM_CalculatePiRange/4k 37970 ns 37972 ns 18453 3.14184
BM_CalculatePiRange/32k 303733 ns 303744 ns 2305 3.14162
BM_CalculatePiRange/256k 2434095 ns 2434186 ns 288 3.1416
BM_CalculatePiRange/1024k 9721140 ns 9721413 ns 71 3.14159
BM_CalculatePi/threads:8 2255 ns 9943 ns 70936
```
Note above the additional header printed when the benchmark changes from
``BM_UserCounter`` to ``BM_Factorial``. This is because ``BM_Factorial`` does
not have the same counter set as ``BM_UserCounter``.
<a name="multithreaded-benchmarks"/>
## Multithreaded Benchmarks
In a multithreaded test (benchmark invoked by multiple threads simultaneously),
it is guaranteed that none of the threads will start until all have reached
the start of the benchmark loop, and all will have finished before any thread
exits the benchmark loop. (This behavior is also provided by the `KeepRunning()`
API) As such, any global setup or teardown can be wrapped in a check against the thread
index:
```c++
static void BM_MultiThreaded(benchmark::State& state) {
if (state.thread_index() == 0) {
// Setup code here.
}
for (auto _ : state) {
// Run the test as normal.
}
if (state.thread_index() == 0) {
// Teardown code here.
}
}
BENCHMARK(BM_MultiThreaded)->Threads(2);
```
To run the benchmark across a range of thread counts, instead of `Threads`, use
`ThreadRange`. This takes two parameters (`min_threads` and `max_threads`) and
runs the benchmark once for values in the inclusive range. For example:
```c++
BENCHMARK(BM_MultiThreaded)->ThreadRange(1, 8);
```
will run `BM_MultiThreaded` with thread counts 1, 2, 4, and 8.
If the benchmarked code itself uses threads and you want to compare it to
single-threaded code, you may want to use real-time ("wallclock") measurements
for latency comparisons:
```c++
BENCHMARK(BM_test)->Range(8, 8<<10)->UseRealTime();
```
Without `UseRealTime`, CPU time is used by default.
### Manual Multithreaded Benchmarks
Google/benchmark uses `std::thread` as multithreading environment per default.
If you want to use another multithreading environment (e.g. OpenMP), you can provide
a factory function to your benchmark using the `ThreadRunner` function.
The factory function takes the number of threads as argument and creates a custom class
derived from `benchmark::ThreadRunnerBase`.
This custom class must override the function
`void RunThreads(const std::function<void(int)>& fn)`.
`RunThreads` is called by the main thread and spawns the requested number of threads.
Each spawned thread must call `fn(thread_index)`, where `thread_index` is its own
thread index. Before `RunThreads` returns, all spawned threads must be joined.
```c++
class OpenMPThreadRunner : public benchmark::ThreadRunnerBase
{
OpenMPThreadRunner(int num_threads)
: num_threads_(num_threads)
{}
void RunThreads(const std::function<void(int)>& fn) final
{
#pragma omp parallel num_threads(num_threads_)
fn(omp_get_thread_num());
}
private:
int num_threads_;
};
BENCHMARK(BM_MultiThreaded)
->ThreadRunner([](int num_threads) {
return std::make_unique<OpenMPThreadRunner>(num_threads);
})
->Threads(1)->Threads(2)->Threads(4);
```
The above example creates a parallel OpenMP region before it enters `BM_MultiThreaded`.
The actual benchmark code can remain the same and is therefore not tied to a specific
thread runner. The measurement does not include the time for creating and joining the
threads.
<a name="cpu-timers" />
## CPU Timers
By default, the CPU timer only measures the time spent by the main thread.
If the benchmark itself uses threads internally, this measurement may not
be what you are looking for. Instead, there is a way to measure the total
CPU usage of the process, by all the threads.
```c++
void callee(int i);
static void MyMain(int size) {
#pragma omp parallel for
for(int i = 0; i < size; i++)
callee(i);
}
static void BM_OpenMP(benchmark::State& state) {
for (auto _ : state)
MyMain(state.range(0));
}
// Measure the time spent by the main thread, use it to decide for how long to
// run the benchmark loop. Depending on the internal implementation detail may
// measure to anywhere from near-zero (the overhead spent before/after work
// handoff to worker thread[s]) to the whole single-thread time.
BENCHMARK(BM_OpenMP)->Range(8, 8<<10);
// Measure the user-visible time, the wall clock (literally, the time that
// has passed on the clock on the wall), use it to decide for how long to
// run the benchmark loop. This will always be meaningful, and will match the
// time spent by the main thread in single-threaded case, in general decreasing
// with the number of internal threads doing the work.
BENCHMARK(BM_OpenMP)->Range(8, 8<<10)->UseRealTime();
// Measure the total CPU consumption, use it to decide for how long to
// run the benchmark loop. This will always measure to no less than the
// time spent by the main thread in single-threaded case.
BENCHMARK(BM_OpenMP)->Range(8, 8<<10)->MeasureProcessCPUTime();
// A mixture of the last two. Measure the total CPU consumption, but use the
// wall clock to decide for how long to run the benchmark loop.
BENCHMARK(BM_OpenMP)->Range(8, 8<<10)->MeasureProcessCPUTime()->UseRealTime();
```
### Controlling Timers
Normally, the entire duration of the work loop (`for (auto _ : state) {}`)
is measured. But sometimes, it is necessary to do some work inside of
that loop, every iteration, but without counting that time to the benchmark time.
That is possible, although it is not recommended, since it has high overhead.
<!-- {% raw %} -->
```c++
static void BM_SetInsert_With_Timer_Control(benchmark::State& state) {
std::set<int> data;
for (auto _ : state) {
state.PauseTiming(); // Stop timers. They will not count until they are resumed.
data = ConstructRandomSet(state.range(0)); // Do something that should not be measured
state.ResumeTiming(); // And resume timers. They are now counting again.
// The rest will be measured.
for (int j = 0; j < state.range(1); ++j)
data.insert(RandomNumber());
}
}
BENCHMARK(BM_SetInsert_With_Timer_Control)->Ranges({{1<<10, 8<<10}, {128, 512}});
```
<!-- {% endraw %} -->
<a name="manual-timing" />
## Manual Timing
For benchmarking something for which neither CPU time nor real-time are
correct or accurate enough, completely manual timing is supported using
the `UseManualTime` function.
When `UseManualTime` is used, the benchmarked code must call
`SetIterationTime` once per iteration of the benchmark loop to
report the manually measured time.
An example use case for this is benchmarking GPU execution (e.g. OpenCL
or CUDA kernels, OpenGL or Vulkan or Direct3D draw calls), which cannot
be accurately measured using CPU time or real-time. Instead, they can be
measured accurately using a dedicated API, and these measurement results
can be reported back with `SetIterationTime`.
```c++
static void BM_ManualTiming(benchmark::State& state) {
int microseconds = state.range(0);
std::chrono::duration<double, std::micro> sleep_duration {
static_cast<double>(microseconds)
};
for (auto _ : state) {
auto start = std::chrono::high_resolution_clock::now();
// Simulate some useful workload with a sleep
std::this_thread::sleep_for(sleep_duration);
auto end = std::chrono::high_resolution_clock::now();
auto elapsed_seconds =
std::chrono::duration_cast<std::chrono::duration<double>>(
end - start);
state.SetIterationTime(elapsed_seconds.count());
}
}
BENCHMARK(BM
gitextract_rtytoi0j/
├── .bazelversion
├── .clang-format
├── .clang-tidy
├── .clang-tidy.ignore
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── dependabot.yml
│ ├── install_bazel.sh
│ ├── libcxx-setup.sh
│ └── workflows/
│ ├── bazel.yml
│ ├── build-and-test-min-cmake.yml
│ ├── build-and-test-perfcounters.yml
│ ├── build-and-test.yml
│ ├── clang-format-lint.yml
│ ├── clang-tidy-lint.yml
│ ├── doxygen.yml
│ ├── ossf.yml
│ ├── pre-commit.yml
│ ├── sanitizer.yml
│ ├── test_bindings.yml
│ └── wheels.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .ycm_extra_conf.py
├── AUTHORS
├── BUILD.bazel
├── CMakeLists.txt
├── CONTRIBUTING.md
├── CONTRIBUTORS
├── LICENSE
├── MODULE.bazel
├── README.md
├── WORKSPACE
├── WORKSPACE.bzlmod
├── _config.yml
├── appveyor.yml
├── bazel/
│ └── benchmark_deps.bzl
├── bindings/
│ └── python/
│ └── google_benchmark/
│ ├── BUILD
│ ├── __init__.py
│ ├── benchmark.cc
│ └── example.py
├── cmake/
│ ├── AddCXXCompilerFlag.cmake
│ ├── CXXFeatureCheck.cmake
│ ├── Config.cmake.in
│ ├── GetGitVersion.cmake
│ ├── GoogleTest.cmake
│ ├── GoogleTest.cmake.in
│ ├── benchmark.pc.in
│ ├── benchmark_main.pc.in
│ ├── gnu_posix_regex.cpp
│ ├── llvm-toolchain.cmake
│ ├── posix_regex.cpp
│ ├── pthread_affinity.cpp
│ ├── split_list.cmake
│ ├── std_regex.cpp
│ ├── steady_clock.cpp
│ └── thread_safety_attributes.cpp
├── docs/
│ ├── AssemblyTests.md
│ ├── _config.yml
│ ├── assets/
│ │ └── images/
│ │ ├── icon.xcf
│ │ └── icon_black.xcf
│ ├── dependencies.md
│ ├── index.md
│ ├── perf_counters.md
│ ├── platform_specific_build_instructions.md
│ ├── python_bindings.md
│ ├── random_interleaving.md
│ ├── reducing_variance.md
│ ├── releasing.md
│ ├── tools.md
│ └── user_guide.md
├── include/
│ └── benchmark/
│ ├── benchmark.h
│ ├── benchmark_api.h
│ ├── counter.h
│ ├── export.h
│ ├── macros.h
│ ├── managers.h
│ ├── registration.h
│ ├── reporter.h
│ ├── state.h
│ ├── statistics.h
│ ├── sysinfo.h
│ ├── types.h
│ └── utils.h
├── pyproject.toml
├── setup.py
├── src/
│ ├── CMakeLists.txt
│ ├── arraysize.h
│ ├── benchmark.cc
│ ├── benchmark_api_internal.cc
│ ├── benchmark_api_internal.h
│ ├── benchmark_main.cc
│ ├── benchmark_name.cc
│ ├── benchmark_register.cc
│ ├── benchmark_register.h
│ ├── benchmark_runner.cc
│ ├── benchmark_runner.h
│ ├── check.cc
│ ├── check.h
│ ├── colorprint.cc
│ ├── colorprint.h
│ ├── commandlineflags.cc
│ ├── commandlineflags.h
│ ├── complexity.cc
│ ├── complexity.h
│ ├── console_reporter.cc
│ ├── counter.cc
│ ├── counter.h
│ ├── csv_reporter.cc
│ ├── cycleclock.h
│ ├── internal_macros.h
│ ├── json_reporter.cc
│ ├── log.h
│ ├── mutex.h
│ ├── perf_counters.cc
│ ├── perf_counters.h
│ ├── re.h
│ ├── reporter.cc
│ ├── statistics.cc
│ ├── statistics.h
│ ├── string_util.cc
│ ├── string_util.h
│ ├── sysinfo.cc
│ ├── thread_manager.h
│ ├── thread_timer.h
│ ├── timers.cc
│ └── timers.h
├── test/
│ ├── AssemblyTests.cmake
│ ├── BUILD
│ ├── CMakeLists.txt
│ ├── args_product_test.cc
│ ├── basic_test.cc
│ ├── benchmark_gtest.cc
│ ├── benchmark_min_time_flag_iters_test.cc
│ ├── benchmark_min_time_flag_time_test.cc
│ ├── benchmark_name_gtest.cc
│ ├── benchmark_random_interleaving_gtest.cc
│ ├── benchmark_setup_teardown_cb_types_gtest.cc
│ ├── benchmark_setup_teardown_test.cc
│ ├── benchmark_test.cc
│ ├── clobber_memory_assembly_test.cc
│ ├── commandlineflags_gtest.cc
│ ├── complexity_test.cc
│ ├── cxx11_test.cc
│ ├── diagnostics_test.cc
│ ├── display_aggregates_only_test.cc
│ ├── donotoptimize_assembly_test.cc
│ ├── donotoptimize_test.cc
│ ├── filter_test.cc
│ ├── fixture_test.cc
│ ├── internal_threading_test.cc
│ ├── link_main_test.cc
│ ├── locale_impermeability_test.cc
│ ├── manual_threading_test.cc
│ ├── map_test.cc
│ ├── memory_manager_test.cc
│ ├── memory_results_gtest.cc
│ ├── min_time_parse_gtest.cc
│ ├── multiple_ranges_test.cc
│ ├── options_test.cc
│ ├── output_test.h
│ ├── output_test_helper.cc
│ ├── overload_test.cc
│ ├── perf_counters_gtest.cc
│ ├── perf_counters_test.cc
│ ├── profiler_manager_gtest.cc
│ ├── profiler_manager_iterations_test.cc
│ ├── profiler_manager_test.cc
│ ├── register_benchmark_test.cc
│ ├── repetitions_test.cc
│ ├── report_aggregates_only_test.cc
│ ├── reporter_output_test.cc
│ ├── skip_with_error_test.cc
│ ├── spec_arg_test.cc
│ ├── spec_arg_verbosity_test.cc
│ ├── state_assembly_test.cc
│ ├── statistics_gtest.cc
│ ├── string_util_gtest.cc
│ ├── templated_fixture_method_test.cc
│ ├── templated_fixture_test.cc
│ ├── time_unit_gtest.cc
│ ├── user_counters_tabular_test.cc
│ ├── user_counters_test.cc
│ ├── user_counters_thousands_test.cc
│ └── user_counters_threads_test.cc
└── tools/
├── BUILD.bazel
├── compare.py
├── gbench/
│ ├── Inputs/
│ │ ├── test1_run1.json
│ │ ├── test1_run2.json
│ │ ├── test2_run.json
│ │ ├── test3_run0.json
│ │ ├── test3_run1.json
│ │ ├── test4_run.json
│ │ ├── test4_run0.json
│ │ ├── test4_run1.json
│ │ ├── test5_run0.json
│ │ └── test5_run1.json
│ ├── __init__.py
│ ├── report.py
│ └── util.py
├── libpfm.BUILD.bazel
├── requirements.txt
└── strip_asm.py
SYMBOL INDEX (893 symbols across 115 files)
FILE: .ycm_extra_conf.py
function DirectoryOfThisScript (line 47) | def DirectoryOfThisScript():
function MakeRelativePathsInFlagsAbsolute (line 51) | def MakeRelativePathsInFlagsAbsolute(flags, working_directory):
function IsHeaderFile (line 80) | def IsHeaderFile(filename):
function GetCompilationInfoForFile (line 85) | def GetCompilationInfoForFile(filename):
function FlagsForFile (line 104) | def FlagsForFile(filename, **kwargs):
FILE: bindings/python/google_benchmark/__init__.py
class __OptionMaker (line 54) | class __OptionMaker:
class Options (line 60) | class Options:
method __init__ (line 64) | def __init__(self, func):
method make (line 69) | def make(cls, func_or_options):
method __getattr__ (line 75) | def __getattr__(self, builder_name):
function register (line 100) | def register(undefined=None, *, name=None):
function main (line 123) | def main(argv: list[str] | None = None) -> None:
FILE: bindings/python/google_benchmark/benchmark.cc
function Initialize (line 16) | std::vector<std::string> Initialize(const std::vector<std::string>& argv) {
function NB_MODULE (line 45) | NB_MODULE(_benchmark, m) {
FILE: bindings/python/google_benchmark/example.py
function empty (line 33) | def empty(state):
function sum_million (line 39) | def sum_million(state):
function pause_timing (line 45) | def pause_timing(state):
function skipped (line 57) | def skipped(state):
function manual_timing (line 67) | def manual_timing(state):
function custom_counters (line 78) | def custom_counters(state):
function with_options (line 103) | def with_options(state):
function with_options2 (line 110) | def with_options2(state):
function passing_argument (line 118) | def passing_argument(state):
function using_range (line 125) | def using_range(state):
function computing_complexity (line 134) | def computing_complexity(state):
FILE: cmake/gnu_posix_regex.cpp
function main (line 3) | int main() {
FILE: cmake/posix_regex.cpp
function main (line 3) | int main() {
FILE: cmake/pthread_affinity.cpp
function main (line 5) | int main() {
FILE: cmake/std_regex.cpp
function main (line 3) | int main() {
FILE: cmake/steady_clock.cpp
function main (line 3) | int main() {
FILE: cmake/thread_safety_attributes.cpp
function main (line 4) | int main() {}
FILE: include/benchmark/benchmark_api.h
function namespace (line 35) | namespace benchmark {
function class (line 263) | class Fixture : public Benchmark {
FILE: include/benchmark/counter.h
function namespace (line 29) | namespace benchmark {
function namespace (line 67) | namespace internal {
FILE: include/benchmark/managers.h
function class (line 27) | class MemoryManager {
FILE: include/benchmark/reporter.h
function BenchmarkName (line 39) | struct BENCHMARK_EXPORT BenchmarkName {
type Context (line 54) | struct Context {
function Run (line 62) | struct BENCHMARK_EXPORT Run {
FILE: include/benchmark/state.h
function namespace (line 32) | namespace benchmark {
function BENCHMARK_ALWAYS_INLINE (line 123) | BENCHMARK_ALWAYS_INLINE
function StateIterator (line 211) | struct State::StateIterator {
FILE: include/benchmark/statistics.h
type BigO (line 25) | enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLa...
type ComplexityN (line 27) | typedef int64_t ComplexityN;
type StatisticUnit (line 29) | enum StatisticUnit { kTime, kPercentage }
function namespace (line 35) | namespace internal {
FILE: include/benchmark/sysinfo.h
function CPUInfo (line 30) | struct BENCHMARK_EXPORT CPUInfo {
function SystemInfo (line 53) | struct BENCHMARK_EXPORT SystemInfo {
FILE: include/benchmark/types.h
function namespace (line 26) | namespace benchmark {
FILE: include/benchmark/utils.h
function namespace (line 24) | namespace benchmark {
FILE: setup.py
function is_cibuildwheel (line 24) | def is_cibuildwheel() -> bool:
function _maybe_patch_toolchains (line 29) | def _maybe_patch_toolchains() -> Generator[None, None, None]:
class BazelExtension (line 64) | class BazelExtension(setuptools.Extension):
method __init__ (line 67) | def __init__(self, name: str, bazel_target: str, **kwargs: Any):
class BuildBazelExtension (line 75) | class BuildBazelExtension(build_ext.build_ext):
method run (line 78) | def run(self):
method copy_extensions_to_source (line 84) | def copy_extensions_to_source(self):
method bazel_build (line 91) | def bazel_build(self, ext: BazelExtension) -> None: # noqa: C901
FILE: src/arraysize.h
function namespace (line 6) | namespace benchmark {
FILE: src/benchmark.cc
type benchmark (line 66) | namespace benchmark {
type internal (line 159) | namespace internal {
function BENCHMARK_EXPORT (line 164) | BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalConte...
function UseCharPointer (line 174) | void UseCharPointer(char const volatile* const v) {
function FlushStreams (line 355) | void FlushStreams(BenchmarkReporter* reporter) {
function Report (line 364) | void Report(BenchmarkReporter* display_reporter,
function RunBenchmarks (line 390) | void RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks,
function BENCHMARK_DISABLE_DEPRECATED_WARNING (line 529) | BENCHMARK_DISABLE_DEPRECATED_WARNING
function IsZero (line 552) | bool IsZero(double n) {
function GetOutputOptions (line 556) | ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) {
function PrintUsageAndExit (line 731) | void PrintUsageAndExit() {
function SetDefaultTimeUnitFromFlag (line 738) | void SetDefaultTimeUnitFromFlag(const std::string& time_unit_flag) {
function ParseCommandLineFlags (line 756) | void ParseCommandLineFlags(int* argc, char** argv) {
function InitializeStreams (line 821) | int InitializeStreams() {
function get_as_unsigned (line 827) | std::make_unsigned_t<T> get_as_unsigned(T v) {
type internal (line 350) | namespace internal {
function BENCHMARK_EXPORT (line 164) | BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalConte...
function UseCharPointer (line 174) | void UseCharPointer(char const volatile* const v) {
function FlushStreams (line 355) | void FlushStreams(BenchmarkReporter* reporter) {
function Report (line 364) | void Report(BenchmarkReporter* display_reporter,
function RunBenchmarks (line 390) | void RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks,
function BENCHMARK_DISABLE_DEPRECATED_WARNING (line 529) | BENCHMARK_DISABLE_DEPRECATED_WARNING
function IsZero (line 552) | bool IsZero(double n) {
function GetOutputOptions (line 556) | ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) {
function PrintUsageAndExit (line 731) | void PrintUsageAndExit() {
function SetDefaultTimeUnitFromFlag (line 738) | void SetDefaultTimeUnitFromFlag(const std::string& time_unit_flag) {
function ParseCommandLineFlags (line 756) | void ParseCommandLineFlags(int* argc, char** argv) {
function InitializeStreams (line 821) | int InitializeStreams() {
function get_as_unsigned (line 827) | std::make_unsigned_t<T> get_as_unsigned(T v) {
function BenchmarkReporter (line 582) | BenchmarkReporter* CreateDefaultDisplayReporter() {
function RunSpecifiedBenchmarks (line 590) | size_t RunSpecifiedBenchmarks() {
function RunSpecifiedBenchmarks (line 594) | size_t RunSpecifiedBenchmarks(std::string spec) {
function RunSpecifiedBenchmarks (line 598) | size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter) {
function RunSpecifiedBenchmarks (line 603) | size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
function RunSpecifiedBenchmarks (line 608) | size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
function RunSpecifiedBenchmarks (line 614) | size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
function TimeUnit (line 691) | TimeUnit GetDefaultTimeUnit() { return default_time_unit; }
function SetDefaultTimeUnit (line 693) | void SetDefaultTimeUnit(TimeUnit unit) { default_time_unit = unit; }
function GetBenchmarkFilter (line 695) | std::string GetBenchmarkFilter() { return FLAGS_benchmark_filter; }
function SetBenchmarkFilter (line 697) | void SetBenchmarkFilter(std::string value) {
function GetBenchmarkVerbosity (line 701) | int32_t GetBenchmarkVerbosity() { return FLAGS_v; }
function RegisterMemoryManager (line 703) | void RegisterMemoryManager(MemoryManager* manager) {
function RegisterProfilerManager (line 707) | void RegisterProfilerManager(ProfilerManager* manager) {
function AddCustomContext (line 715) | void AddCustomContext(std::string key, std::string value) {
type internal (line 726) | namespace internal {
function BENCHMARK_EXPORT (line 164) | BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalConte...
function UseCharPointer (line 174) | void UseCharPointer(char const volatile* const v) {
function FlushStreams (line 355) | void FlushStreams(BenchmarkReporter* reporter) {
function Report (line 364) | void Report(BenchmarkReporter* display_reporter,
function RunBenchmarks (line 390) | void RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks,
function BENCHMARK_DISABLE_DEPRECATED_WARNING (line 529) | BENCHMARK_DISABLE_DEPRECATED_WARNING
function IsZero (line 552) | bool IsZero(double n) {
function GetOutputOptions (line 556) | ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) {
function PrintUsageAndExit (line 731) | void PrintUsageAndExit() {
function SetDefaultTimeUnitFromFlag (line 738) | void SetDefaultTimeUnitFromFlag(const std::string& time_unit_flag) {
function ParseCommandLineFlags (line 756) | void ParseCommandLineFlags(int* argc, char** argv) {
function InitializeStreams (line 821) | int InitializeStreams() {
function get_as_unsigned (line 827) | std::make_unsigned_t<T> get_as_unsigned(T v) {
function MaybeReenterWithoutASLR (line 834) | void MaybeReenterWithoutASLR(int /*argc*/, char** argv) {
function GetBenchmarkVersion (line 871) | std::string GetBenchmarkVersion() {
function PrintDefaultHelp (line 879) | void PrintDefaultHelp() {
function Initialize (line 904) | void Initialize(int* argc, char** argv, void (*HelperPrintf)()) {
function Shutdown (line 910) | void Shutdown() { delete internal::global_context; }
function ReportUnrecognizedArguments (line 912) | bool ReportUnrecognizedArguments(int argc, char** argv) {
FILE: src/benchmark_api_internal.cc
type benchmark (line 7) | namespace benchmark {
type internal (line 8) | namespace internal {
function State (line 92) | State BenchmarkInstance::Run(
FILE: src/benchmark_api_internal.h
function namespace (line 17) | namespace internal {
FILE: src/benchmark_name.cc
type benchmark (line 18) | namespace benchmark {
function size_impl (line 23) | size_t size_impl() { return 0; }
function size_impl (line 26) | size_t size_impl(const Head& head, const Tail&... tail) {
function join_impl (line 32) | void join_impl(std::string& /*unused*/, char /*unused*/) {}
function join_impl (line 35) | void join_impl(std::string& s, const char delimiter, const Head& head,
function join (line 47) | std::string join(char delimiter, const Ts&... ts) {
function BENCHMARK_EXPORT (line 55) | BENCHMARK_EXPORT
FILE: src/benchmark_register.cc
type benchmark (line 57) | namespace benchmark {
type internal (line 70) | namespace internal {
class BenchmarkFamilies (line 78) | class BenchmarkFamilies {
method BenchmarkFamilies (line 95) | BenchmarkFamilies() {}
function BenchmarkFamilies (line 101) | BenchmarkFamilies* BenchmarkFamilies::GetInstance() {
method BenchmarkFamilies (line 95) | BenchmarkFamilies() {}
function FindBenchmarksInternal (line 210) | bool FindBenchmarksInternal(const std::string& re,
function Benchmark (line 245) | Benchmark* Benchmark::Name(const std::string& name) {
function Benchmark (line 250) | Benchmark* Benchmark::Arg(int64_t x) {
function Benchmark (line 256) | Benchmark* Benchmark::Unit(TimeUnit unit) {
function Benchmark (line 262) | Benchmark* Benchmark::Range(int64_t start, int64_t limit) {
function Benchmark (line 273) | Benchmark* Benchmark::Ranges(
function Benchmark (line 287) | Benchmark* Benchmark::ArgsProduct(
function Benchmark (line 315) | Benchmark* Benchmark::ArgName(const std::string& name) {
function Benchmark (line 321) | Benchmark* Benchmark::ArgNames(const std::vector<std::string>& names) {
function Benchmark (line 327) | Benchmark* Benchmark::DenseRange(int64_t start, int64_t limit, int ste...
function Benchmark (line 336) | Benchmark* Benchmark::Args(const std::vector<int64_t>& args) {
function Benchmark (line 342) | Benchmark* Benchmark::Apply(
function Benchmark (line 348) | Benchmark* Benchmark::Setup(callback_function&& setup) {
function Benchmark (line 354) | Benchmark* Benchmark::Setup(const callback_function& setup) {
function Benchmark (line 360) | Benchmark* Benchmark::Teardown(callback_function&& teardown) {
function Benchmark (line 366) | Benchmark* Benchmark::Teardown(const callback_function& teardown) {
function Benchmark (line 372) | Benchmark* Benchmark::RangeMultiplier(int multiplier) {
function Benchmark (line 378) | Benchmark* Benchmark::MinTime(double t) {
function Benchmark (line 385) | Benchmark* Benchmark::MinWarmUpTime(double t) {
function Benchmark (line 392) | Benchmark* Benchmark::Iterations(IterationCount n) {
function Benchmark (line 400) | Benchmark* Benchmark::Repetitions(int n) {
function Benchmark (line 406) | Benchmark* Benchmark::ReportAggregatesOnly(bool value) {
function Benchmark (line 412) | Benchmark* Benchmark::DisplayAggregatesOnly(bool value) {
function Benchmark (line 429) | Benchmark* Benchmark::MeasureProcessCPUTime() {
function Benchmark (line 435) | Benchmark* Benchmark::UseRealTime() {
function Benchmark (line 442) | Benchmark* Benchmark::UseManualTime() {
function Benchmark (line 449) | Benchmark* Benchmark::Complexity(BigO complexity) {
function Benchmark (line 454) | Benchmark* Benchmark::Complexity(BigOFunc* complexity) {
function Benchmark (line 460) | Benchmark* Benchmark::ComputeStatistics(const std::string& name,
function Benchmark (line 467) | Benchmark* Benchmark::Threads(int t) {
function Benchmark (line 473) | Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) {
function Benchmark (line 481) | Benchmark* Benchmark::DenseThreadRange(int min_threads, int max_threads,
function Benchmark (line 494) | Benchmark* Benchmark::ThreadPerCpu() {
function Benchmark (line 499) | Benchmark* Benchmark::ThreadRunner(threadrunner_factory&& factory) {
function TimeUnit (line 525) | TimeUnit Benchmark::GetTimeUnit() const {
type internal (line 529) | namespace internal {
class BenchmarkFamilies (line 78) | class BenchmarkFamilies {
method BenchmarkFamilies (line 95) | BenchmarkFamilies() {}
function BenchmarkFamilies (line 101) | BenchmarkFamilies* BenchmarkFamilies::GetInstance() {
method BenchmarkFamilies (line 95) | BenchmarkFamilies() {}
function FindBenchmarksInternal (line 210) | bool FindBenchmarksInternal(const std::string& re,
function ClearRegisteredBenchmarks (line 539) | void ClearRegisteredBenchmarks() {
function CreateRange (line 543) | std::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi) {
function CreateDenseRange (line 549) | std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, in...
FILE: src/benchmark_register.h
function namespace (line 11) | namespace benchmark {
FILE: src/benchmark_runner.cc
type benchmark (line 64) | namespace benchmark {
type internal (line 74) | namespace internal {
function CreateRunReport (line 86) | BenchmarkReporter::Run CreateRunReport(
function RunInThread (line 144) | void RunInThread(const BenchmarkInstance* b, IterationCount iters,
function ComputeMinTime (line 173) | double ComputeMinTime(const benchmark::internal::BenchmarkInstance& b,
function IterationCount (line 187) | IterationCount ComputeIters(const benchmark::internal::BenchmarkInst...
class ThreadRunnerDefault (line 199) | class ThreadRunnerDefault : public ThreadRunnerBase {
method ThreadRunnerDefault (line 201) | explicit ThreadRunnerDefault(int num_threads)
method RunThreads (line 204) | void RunThreads(const std::function<void(int)>& fn) override final {
function GetThreadRunner (line 224) | std::unique_ptr<ThreadRunnerBase> GetThreadRunner(
function BenchTimeType (line 234) | BenchTimeType ParseBenchMinTime(const std::string& value) {
function IterationCount (line 373) | IterationCount BenchmarkRunner::PredictNumItersNeeded(
function RunResults (line 573) | RunResults&& BenchmarkRunner::GetResults() {
FILE: src/benchmark_runner.h
function namespace (line 26) | namespace benchmark {
FILE: src/check.cc
type benchmark (line 3) | namespace benchmark {
type internal (line 4) | namespace internal {
function BENCHMARK_EXPORT (line 11) | BENCHMARK_EXPORT AbortHandlerT*& GetAbortHandler() { return handler; }
FILE: src/check.h
function namespace (line 30) | namespace benchmark {
FILE: src/colorprint.cc
type benchmark (line 34) | namespace benchmark {
function PlatformColorCode (line 42) | PlatformColorCode GetPlatformColorCode(LogColor color) {
function FormatString (line 85) | std::string FormatString(const char* msg, va_list args) {
function FormatString (line 116) | std::string FormatString(const char* msg, ...) {
function ColorPrintf (line 124) | void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ....
function ColorPrintf (line 131) | void ColorPrintf(std::ostream& out, LogColor color, const char* fmt,
function IsColorTerminal (line 169) | bool IsColorTerminal() {
FILE: src/colorprint.h
function namespace (line 10) | namespace benchmark {
FILE: src/commandlineflags.cc
type benchmark (line 28) | namespace benchmark {
function ParseInt32 (line 34) | bool ParseInt32(const std::string& src_text, const char* str, int32_t*...
function ParseDouble (line 68) | bool ParseDouble(const std::string& src_text, const char* str, double*...
function ParseKvPairs (line 87) | bool ParseKvPairs(const std::string& src_text, const char* str,
function FlagToEnvVar (line 112) | std::string FlagToEnvVar(const char* flag) {
function BENCHMARK_EXPORT (line 125) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 132) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 145) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 158) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 165) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 224) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 239) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 254) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 269) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 283) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 303) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 308) | BENCHMARK_EXPORT
FILE: src/commandlineflags.h
function namespace (line 41) | namespace benchmark {
FILE: src/complexity.cc
type benchmark (line 27) | namespace benchmark {
function BigOFunc (line 32) | BigOFunc* FittingCurve(BigO complexity) {
function GetBigOString (line 57) | std::string GetBigOString(BigO complexity) {
function LeastSq (line 88) | LeastSq MinimalLeastSq(const std::vector<ComplexityN>& n,
function LeastSq (line 130) | LeastSq MinimalLeastSq(const std::vector<ComplexityN>& n,
function ComputeBigO (line 164) | std::vector<BenchmarkReporter::Run> ComputeBigO(
FILE: src/console_reporter.cc
type benchmark (line 36) | namespace benchmark {
function BENCHMARK_EXPORT (line 38) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 62) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 80) | BENCHMARK_EXPORT
function IgnoreColorPrint (line 103) | static void IgnoreColorPrint(std::ostream& out, LogColor /*unused*/,
function FormatTime (line 111) | static std::string FormatTime(double time) {
function BENCHMARK_EXPORT (line 133) | BENCHMARK_EXPORT
FILE: src/counter.cc
type benchmark (line 17) | namespace benchmark {
type internal (line 18) | namespace internal {
function Finish (line 22) | double Finish(Counter const& c, IterationCount iterations, double cp...
function Finish (line 46) | void Finish(UserCounters* l, IterationCount iterations, double cpu_t...
function Increment (line 53) | void Increment(UserCounters* l, UserCounters const& r) {
function SameNames (line 70) | bool SameNames(UserCounters const& l, UserCounters const& r) {
FILE: src/counter.h
function namespace (line 22) | namespace benchmark {
FILE: src/csv_reporter.cc
type benchmark (line 26) | namespace benchmark {
function CsvEscape (line 34) | std::string CsvEscape(const std::string& s) {
function BENCHMARK_EXPORT (line 51) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 57) | BENCHMARK_EXPORT
function BENCHMARK_EXPORT (line 110) | BENCHMARK_EXPORT
FILE: src/cycleclock.h
function namespace (line 57) | namespace benchmark {
FILE: src/json_reporter.cc
type benchmark (line 33) | namespace benchmark {
function StrEscape (line 36) | std::string StrEscape(const std::string& s) {
function FormatKV (line 70) | std::string FormatKV(std::string const& key, std::string const& value) {
function FormatKV (line 75) | std::string FormatKV(std::string const& key, const char* value) {
function FormatKV (line 80) | std::string FormatKV(std::string const& key, bool value) {
function FormatKV (line 85) | std::string FormatKV(std::string const& key, int64_t value) {
function FormatKV (line 93) | std::string FormatKV(std::string const& key, int value) {
function FormatKV (line 97) | std::string FormatKV(std::string const& key, double value) {
function RoundDouble (line 115) | int64_t RoundDouble(double v) { return std::lround(v); }
FILE: src/log.h
function namespace (line 7) | namespace benchmark {
FILE: src/mutex.h
function namespace (line 67) | namespace benchmark {
FILE: src/perf_counters.cc
type benchmark (line 32) | namespace benchmark {
type internal (line 33) | namespace internal {
function QueryCPUPMUTypes (line 88) | static std::optional<std::vector<uint64_t>> QueryCPUPMUTypes() {
function GetPMUTypesForEvent (line 127) | static std::vector<uint64_t> GetPMUTypesForEvent(const perf_event_at...
function PerfCounters (line 137) | PerfCounters PerfCounters::Create(
function PerfCounters (line 313) | PerfCounters PerfCounters::Create(
function PerfCounters (line 330) | PerfCounters& PerfCounters::operator=(PerfCounters&& other) noexcept {
FILE: src/perf_counters.h
function namespace (line 42) | namespace benchmark {
FILE: src/re.h
function class (line 63) | class Regex {
function Init (line 92) | inline bool Regex::Init(const std::string& spec, std::string* error) {
FILE: src/reporter.cc
type benchmark (line 30) | namespace benchmark {
FILE: src/statistics.cc
type benchmark (line 29) | namespace benchmark {
function StatisticsMean (line 35) | double StatisticsMean(const std::vector<double>& v) {
function StatisticsMedian (line 42) | double StatisticsMedian(const std::vector<double>& v) {
function StatisticsStdDev (line 77) | double StatisticsStdDev(const std::vector<double>& v) {
function StatisticsCV (line 95) | double StatisticsCV(const std::vector<double>& v) {
function ComputeStats (line 110) | std::vector<BenchmarkReporter::Run> ComputeStats(
FILE: src/statistics.h
function namespace (line 24) | namespace benchmark {
FILE: src/string_util.cc
type benchmark (line 16) | namespace benchmark {
function ToExponentAndMantissa (line 34) | std::pair<std::string, int64_t> ToExponentAndMantissa(double val, int ...
function ExponentToPrefix (line 95) | std::string ExponentToPrefix(int64_t exponent, bool iec) {
function ToBinaryStringFullySpecified (line 111) | std::string ToBinaryStringFullySpecified(double value, int precision,
function StrFormatImp (line 119) | std::string StrFormatImp(const char* msg, va_list args) {
function HumanReadableNumber (line 157) | std::string HumanReadableNumber(double n, Counter::OneK one_k) {
function StrFormat (line 161) | std::string StrFormat(const char* format, ...) {
function StrSplit (line 169) | std::vector<std::string> StrSplit(const std::string& str, char delim) {
function stoul (line 191) | unsigned long stoul(const std::string& str, size_t* pos, int base) {
function stoi (line 217) | int stoi(const std::string& str, size_t* pos, int base) {
function stod (line 243) | double stod(const std::string& str, size_t* pos) {
FILE: src/string_util.h
function namespace (line 13) | namespace benchmark {
FILE: src/sysinfo.cc
type benchmark (line 93) | namespace benchmark {
function PrintImp (line 96) | void PrintImp(std::ostream& out) { out << '\n'; }
function PrintImp (line 99) | void PrintImp(std::ostream& out, First&& f, Rest&&... rest) {
function BENCHMARK_NORETURN (line 105) | BENCHMARK_NORETURN void PrintErrorAndDie(Args&&... args) {
type ValueUnion (line 115) | struct ValueUnion {
method ValueUnion (line 129) | ValueUnion() : size(0), buff(nullptr, &std::free) {}
method ValueUnion (line 131) | explicit ValueUnion(std::size_t buff_size)
method ValueUnion (line 135) | ValueUnion(ValueUnion&& other) = default;
method GetAsString (line 141) | std::string GetAsString() const { return std::string(data()); }
method GetAsInteger (line 143) | int64_t GetAsInteger() const {
method GetAsArray (line 152) | std::array<T, N> GetAsArray() {
function ValueUnion (line 161) | ValueUnion GetSysctlImp(std::string const& name) {
method ValueUnion (line 129) | ValueUnion() : size(0), buff(nullptr, &std::free) {}
method ValueUnion (line 131) | explicit ValueUnion(std::size_t buff_size)
method ValueUnion (line 135) | ValueUnion(ValueUnion&& other) = default;
method GetAsString (line 141) | std::string GetAsString() const { return std::string(data()); }
method GetAsInteger (line 143) | int64_t GetAsInteger() const {
method GetAsArray (line 152) | std::array<T, N> GetAsArray() {
function BENCHMARK_MAYBE_UNUSED (line 193) | BENCHMARK_MAYBE_UNUSED
function GetSysctl (line 204) | bool GetSysctl(std::string const& name, Tp* out) {
function GetSysctl (line 213) | bool GetSysctl(std::string const& name, std::array<Tp, N>* out) {
function ReadFromFile (line 222) | bool ReadFromFile(std::string const& fname, ArgT* arg) {
function CpuScaling (line 232) | CPUInfo::Scaling CpuScaling(int num_cpus) {
function CountSetBitsInCPUMap (line 257) | int CountSetBitsInCPUMap(std::string val) {
function BENCHMARK_MAYBE_UNUSED (line 276) | BENCHMARK_MAYBE_UNUSED
function GetCacheSizesMacOSX (line 322) | std::vector<CPUInfo::CacheInfo> GetCacheSizesMacOSX() {
function GetCacheSizesWindows (line 349) | std::vector<CPUInfo::CacheInfo> GetCacheSizesWindows() {
function GetCacheSizesQNX (line 404) | std::vector<CPUInfo::CacheInfo> GetCacheSizesQNX() {
function GetCacheSizes (line 441) | std::vector<CPUInfo::CacheInfo> GetCacheSizes() {
function GetSystemName (line 456) | std::string GetSystemName() {
function GetASLR (line 509) | SystemInfo::ASLR GetASLR() {
function GetNumCPUsImpl (line 520) | int GetNumCPUsImpl() {
function GetNumCPUs (line 566) | int GetNumCPUs() {
class ThreadAffinityGuard (line 576) | class ThreadAffinityGuard final {
method ThreadAffinityGuard (line 578) | ThreadAffinityGuard() : reset_affinity(SetAffinity()) {
method ThreadAffinityGuard (line 605) | ThreadAffinityGuard(ThreadAffinityGuard&&) = delete;
method ThreadAffinityGuard (line 606) | ThreadAffinityGuard(const ThreadAffinityGuard&) = delete;
method ThreadAffinityGuard (line 607) | ThreadAffinityGuard& operator=(ThreadAffinityGuard&&) = delete;
method ThreadAffinityGuard (line 608) | ThreadAffinityGuard& operator=(const ThreadAffinityGuard&) = delete;
method SetAffinity (line 611) | bool SetAffinity() {
function GetCPUCyclesPerSecond (line 662) | double GetCPUCyclesPerSecond(CPUInfo::Scaling scaling) {
function GetLoadAvg (line 870) | std::vector<double> GetLoadAvg() {
function CPUInfo (line 891) | const CPUInfo& CPUInfo::Get() {
function SystemInfo (line 903) | const SystemInfo& SystemInfo::Get() {
FILE: src/thread_manager.h
function namespace (line 11) | namespace benchmark {
FILE: src/thread_timer.h
function namespace (line 7) | namespace benchmark {
FILE: src/timers.cc
type benchmark (line 65) | namespace benchmark {
function MakeTime (line 77) | double MakeTime(FILETIME const& kernel_time, FILETIME const& user_time) {
function MakeTime (line 90) | double MakeTime(struct rusage const& ru) {
function MakeTime (line 98) | double MakeTime(thread_basic_info_data_t const& info) {
function MakeTime (line 106) | double MakeTime(struct timespec const& ts) {
function BENCHMARK_NORETURN (line 112) | BENCHMARK_NORETURN void DiagnoseAndExit(const char* msg) {
function ProcessCPUUsage (line 120) | double ProcessCPUUsage() {
function ThreadCPUUsage (line 168) | double ThreadCPUUsage() {
function LocalDateTimeString (line 226) | std::string LocalDateTimeString() {
FILE: src/timers.h
function namespace (line 7) | namespace benchmark {
FILE: test/args_product_test.cc
class ArgsProductFixture (line 11) | class ArgsProductFixture : public ::benchmark::Fixture {
method ArgsProductFixture (line 13) | ArgsProductFixture()
method SetUp (line 29) | void SetUp(const ::benchmark::State& state) override {
FILE: test/basic_test.cc
function BM_empty (line 10) | void BM_empty(benchmark::State& state) {
function BM_spin_empty (line 20) | void BM_spin_empty(benchmark::State& state) {
function BM_spin_pause_before (line 30) | void BM_spin_pause_before(benchmark::State& state) {
function BM_spin_pause_during (line 43) | void BM_spin_pause_during(benchmark::State& state) {
function BM_pause_during (line 58) | void BM_pause_during(benchmark::State& state) {
function BM_spin_pause_after (line 69) | void BM_spin_pause_after(benchmark::State& state) {
function BM_spin_pause_before_and_after (line 82) | void BM_spin_pause_before_and_after(benchmark::State& state) {
function BM_empty_stop_start (line 98) | void BM_empty_stop_start(benchmark::State& state) {
function BM_KeepRunning (line 105) | void BM_KeepRunning(benchmark::State& state) {
function BM_KeepRunningBatch (line 115) | void BM_KeepRunningBatch(benchmark::State& state) {
function BM_RangedFor (line 141) | void BM_RangedFor(benchmark::State& state) {
function BM_OneTemplateFunc (line 151) | void BM_OneTemplateFunc(benchmark::State& state) {
function BM_TwoTemplateFunc (line 162) | void BM_TwoTemplateFunc(benchmark::State& state) {
FILE: test/benchmark_gtest.cc
type benchmark (line 10) | namespace benchmark {
type internal (line 11) | namespace internal {
function TEST (line 15) | TEST(AddRangeTest, Simple) {
function TEST (line 21) | TEST(AddRangeTest, Simple64) {
function TEST (line 27) | TEST(AddRangeTest, Advanced) {
function TEST (line 33) | TEST(AddRangeTest, Advanced64) {
function TEST (line 39) | TEST(AddRangeTest, FullRange8) {
function TEST (line 46) | TEST(AddRangeTest, FullRange64) {
function TEST (line 55) | TEST(AddRangeTest, NegativeRanges) {
function TEST (line 61) | TEST(AddRangeTest, StrictlyNegative) {
function TEST (line 67) | TEST(AddRangeTest, SymmetricNegativeRanges) {
function TEST (line 73) | TEST(AddRangeTest, SymmetricNegativeRangesOddMult) {
function TEST (line 79) | TEST(AddRangeTest, NegativeRangesAsymmetric) {
function TEST (line 85) | TEST(AddRangeTest, NegativeRangesLargeStep) {
function TEST (line 92) | TEST(AddRangeTest, ZeroOnlyRange) {
function TEST (line 98) | TEST(AddRangeTest, ZeroStartingRange) {
function TEST (line 104) | TEST(AddRangeTest, NegativeRange64) {
function TEST (line 110) | TEST(AddRangeTest, NegativeRangePreservesExistingOrder) {
function TEST (line 118) | TEST(AddRangeTest, FullNegativeRange64) {
function TEST (line 131) | TEST(AddRangeTest, Simple8) {
function TEST (line 138) | TEST(AddCustomContext, Simple) {
function TEST (line 153) | TEST(AddCustomContext, DuplicateKey) {
FILE: test/benchmark_min_time_flag_iters_test.cc
class TestReporter (line 16) | class TestReporter : public benchmark::ConsoleReporter {
method ReportContext (line 18) | bool ReportContext(const Context& context) override {
method ReportRuns (line 22) | void ReportRuns(const std::vector<Run>& report) override {
method TestReporter (line 28) | TestReporter() {}
function BM_MyBench (line 40) | void BM_MyBench(benchmark::State& state) {
function main (line 48) | int main(int argc, char** argv) {
FILE: test/benchmark_min_time_flag_time_test.cc
class TestReporter (line 23) | class TestReporter : public benchmark::ConsoleReporter {
method ReportContext (line 25) | bool ReportContext(const Context& context) override {
method ReportRuns (line 29) | void ReportRuns(const std::vector<Run>& report) override {
method ReportRunsConfig (line 34) | void ReportRunsConfig(double min_time, bool /* has_explicit_iters */,
method TestReporter (line 39) | TestReporter() {}
function AlmostEqual (line 49) | bool AlmostEqual(double a, double b) {
function DoTestHelper (line 53) | void DoTestHelper(int* argc, const char** argv, double expected) {
function BM_MyBench (line 66) | void BM_MyBench(benchmark::State& state) {
function main (line 74) | int main(int argc, char** argv) {
FILE: test/benchmark_name_gtest.cc
function TEST (line 9) | TEST(BenchmarkNameTest, Empty) {
function TEST (line 14) | TEST(BenchmarkNameTest, FunctionName) {
function TEST (line 20) | TEST(BenchmarkNameTest, FunctionNameAndArgs) {
function TEST (line 27) | TEST(BenchmarkNameTest, MinTime) {
function TEST (line 35) | TEST(BenchmarkNameTest, MinWarmUpTime) {
function TEST (line 43) | TEST(BenchmarkNameTest, Iterations) {
function TEST (line 51) | TEST(BenchmarkNameTest, Repetitions) {
function TEST (line 59) | TEST(BenchmarkNameTest, TimeType) {
function TEST (line 67) | TEST(BenchmarkNameTest, Threads) {
function TEST (line 75) | TEST(BenchmarkNameTest, TestEmptyFunctionName) {
FILE: test/benchmark_random_interleaving_gtest.cc
type benchmark (line 14) | namespace benchmark {
type internal (line 20) | namespace internal {
class EventQueue (line 23) | class EventQueue : public std::queue<std::string> {
method Put (line 25) | void Put(const std::string& event) { push(event); }
method Clear (line 27) | void Clear() {
method Get (line 33) | std::string Get() {
class NullReporter (line 43) | class NullReporter : public BenchmarkReporter {
method ReportContext (line 45) | bool ReportContext(const Context& /*context*/) override { return t...
method ReportRuns (line 46) | void ReportRuns(const std::vector<Run>& /* report */) override {}
class BenchmarkTest (line 49) | class BenchmarkTest : public testing::Test {
method SetupHook (line 51) | static void SetupHook(int /* num_threads */) { queue->push("Setup"...
method TeardownHook (line 53) | static void TeardownHook(int /* num_threads */) { queue->push("Tea...
method Execute (line 55) | static void Execute(const std::string& pattern) {
function BM_Match1 (line 66) | void BM_Match1(benchmark::State& state) {
function TEST_F (line 82) | TEST_F(BenchmarkTest, Match1) {
function TEST_F (line 95) | TEST_F(BenchmarkTest, Match1WithRepetition) {
function TEST_F (line 106) | TEST_F(BenchmarkTest, Match1WithRandomInterleaving) {
FILE: test/benchmark_setup_teardown_cb_types_gtest.cc
type Functor (line 16) | struct Functor {
class NullReporter (line 20) | class NullReporter : public BenchmarkReporter {
method ReportContext (line 22) | bool ReportContext(const Context& /*context*/) override { return true; }
method ReportRuns (line 23) | void ReportRuns(const std::vector<Run>& /* report */) override {}
class BenchmarkTest (line 26) | class BenchmarkTest : public testing::Test {
method SetUp (line 34) | void SetUp() override {
method TearDown (line 46) | void TearDown() override { ClearRegisteredBenchmarks(); }
function TEST_F (line 50) | TEST_F(BenchmarkTest, LambdaTestCopy) {
function TEST_F (line 61) | TEST_F(BenchmarkTest, LambdaTestMove) {
function TEST_F (line 72) | TEST_F(BenchmarkTest, CallbackFunctionCopy) {
function TEST_F (line 85) | TEST_F(BenchmarkTest, CallbackFunctionMove) {
function TEST_F (line 98) | TEST_F(BenchmarkTest, FunctorCopy) {
function TEST_F (line 107) | TEST_F(BenchmarkTest, FunctorMove) {
function TEST_F (line 117) | TEST_F(BenchmarkTest, NullptrTest) {
FILE: test/benchmark_setup_teardown_test.cc
type singlethreaded (line 14) | namespace singlethreaded {
function DoSetup1 (line 19) | static void DoSetup1(const benchmark::State& state) {
function DoTeardown1 (line 26) | static void DoTeardown1(const benchmark::State& state) {
function BM_with_setup (line 31) | static void BM_with_setup(benchmark::State& state) {
type concurrent (line 46) | namespace concurrent {
function DoSetup2 (line 52) | void DoSetup2(const benchmark::State& state) {
function DoTeardown2 (line 57) | void DoTeardown2(const benchmark::State& state) {
function BM_concurrent (line 62) | void BM_concurrent(benchmark::State& state) {
type fixture_interaction (line 77) | namespace fixture_interaction {
class FIXTURE_BECHMARK_NAME (line 84) | class FIXTURE_BECHMARK_NAME : public ::benchmark::Fixture {
method SetUp (line 86) | void SetUp(const ::benchmark::State& /*unused*/) override {
function DoSetupWithFixture (line 98) | void DoSetupWithFixture(const benchmark::State& /*unused*/) {
type repetitions (line 112) | namespace repetitions {
function DoSetupWithRepetitions (line 116) | void DoSetupWithRepetitions(const benchmark::State& /*unused*/) {
function BM_WithRep (line 119) | void BM_WithRep(benchmark::State& state) {
function main (line 134) | int main(int argc, char** argv) {
FILE: test/benchmark_test.cc
function CalculatePi (line 36) | double CalculatePi(int depth) {
function ConstructRandomSet (line 46) | std::set<int64_t> ConstructRandomSet(int64_t size) {
function BM_Factorial (line 59) | void BM_Factorial(benchmark::State& state) {
function BM_CalculatePiRange (line 72) | void BM_CalculatePiRange(benchmark::State& state) {
function BM_CalculatePi (line 83) | void BM_CalculatePi(benchmark::State& state) {
function BM_SetInsert (line 94) | void BM_SetInsert(benchmark::State& state) {
function BM_Sequential (line 116) | void BM_Sequential(benchmark::State& state) {
function BM_StringCompare (line 134) | void BM_StringCompare(benchmark::State& state) {
function BM_SetupTeardown (line 145) | void BM_SetupTeardown(benchmark::State& state) {
function BM_LongTest (line 166) | void BM_LongTest(benchmark::State& state) {
function BM_ParallelMemset (line 176) | void BM_ParallelMemset(benchmark::State& state) {
function BM_ManualTiming (line 200) | void BM_ManualTiming(benchmark::State& state) {
function BM_with_args (line 225) | void BM_with_args(benchmark::State& state, Args&&...) {
function BM_non_template_args (line 233) | void BM_non_template_args(benchmark::State& state, int, double) {
function BM_template2_capture (line 240) | void BM_template2_capture(benchmark::State& state, ExtraArgs&&... extra_...
function BENCHMARK_TEMPLATE2_CAPTURE (line 249) | BENCHMARK_TEMPLATE2_CAPTURE(BM_template2_capture, void, char*, foo, 42U);
FILE: test/clobber_memory_assembly_test.cc
function test_basic (line 17) | void test_basic() {
function test_redundant_store (line 28) | void test_redundant_store() {
function test_redundant_read (line 38) | void test_redundant_read() {
function test_redundant_read2 (line 52) | void test_redundant_read2() {
FILE: test/commandlineflags_gtest.cc
type benchmark (line 8) | namespace benchmark {
function setenv (line 12) | int setenv(const char* name, const char* value, int overwrite) {
function unsetenv (line 23) | int unsetenv(const char* name) { return _putenv_s(name, ""); }
function TEST (line 27) | TEST(BoolFromEnv, Default) {
function TEST (line 32) | TEST(BoolFromEnv, False) {
function TEST (line 90) | TEST(BoolFromEnv, True) {
function TEST (line 154) | TEST(Int32FromEnv, NotInEnv) {
function TEST (line 159) | TEST(Int32FromEnv, InvalidInteger) {
function TEST (line 165) | TEST(Int32FromEnv, ValidInteger) {
function TEST (line 171) | TEST(DoubleFromEnv, NotInEnv) {
function TEST (line 176) | TEST(DoubleFromEnv, InvalidReal) {
function TEST (line 182) | TEST(DoubleFromEnv, ValidReal) {
function TEST (line 188) | TEST(StringFromEnv, Default) {
function TEST (line 193) | TEST(StringFromEnv, Valid) {
function TEST (line 199) | TEST(KvPairsFromEnv, Default) {
function TEST (line 205) | TEST(KvPairsFromEnv, MalformedReturnsDefault) {
function TEST (line 212) | TEST(KvPairsFromEnv, Single) {
function TEST (line 219) | TEST(KvPairsFromEnv, Multiple) {
FILE: test/complexity_test.cc
function AddComplexityTest (line 20) | int AddComplexityTest(const std::string& test_name,
function BM_Complexity_O1 (line 72) | void BM_Complexity_O1(benchmark::State& state) {
function BM_Complexity_O_N (line 121) | void BM_Complexity_O_N(benchmark::State& state) {
function BM_Complexity_O_N_log_N (line 179) | void BM_Complexity_O_N_log_N(benchmark::State& state) {
function BM_ComplexityCaptureArgs (line 241) | void BM_ComplexityCaptureArgs(benchmark::State& state, int n) {
function main (line 275) | int main(int argc, char* argv[]) {
FILE: test/diagnostics_test.cc
function TestHandler (line 24) | void TestHandler() {
function try_invalid_pause_resume (line 32) | void try_invalid_pause_resume(benchmark::State& state) {
function BM_diagnostic_test (line 50) | void BM_diagnostic_test(benchmark::State& state) {
function BM_diagnostic_test_keep_running (line 71) | void BM_diagnostic_test_keep_running(benchmark::State& state) {
function main (line 93) | int main(int argc, char* argv[]) {
FILE: test/display_aggregates_only_test.cc
function BM_SummaryRepeat (line 16) | void BM_SummaryRepeat(benchmark::State& state) {
function main (line 23) | int main(int argc, char* argv[]) {
FILE: test/donotoptimize_assembly_test.cc
function Add42 (line 19) | inline int Add42(int x) { return x + 42; }
type NotTriviallyCopyable (line 21) | struct NotTriviallyCopyable {
method NotTriviallyCopyable (line 23) | explicit NotTriviallyCopyable(int x) : value(x) {}
type Large (line 28) | struct Large {
type ExtraLarge (line 33) | struct ExtraLarge {
function test_with_rvalue (line 42) | void test_with_rvalue() {
function test_with_large_rvalue (line 49) | void test_with_large_rvalue() {
function test_with_non_trivial_rvalue (line 59) | void test_with_non_trivial_rvalue() {
function test_with_lvalue (line 66) | void test_with_lvalue() {
function test_with_large_lvalue (line 75) | void test_with_large_lvalue() {
function test_with_extra_large_lvalue_with_op (line 86) | void test_with_extra_large_lvalue_with_op() {
function test_with_big_array_with_op (line 94) | void test_with_big_array_with_op() {
function test_with_non_trivial_lvalue (line 102) | void test_with_non_trivial_lvalue() {
function test_with_const_lvalue (line 111) | void test_with_const_lvalue() {
function test_with_large_const_lvalue (line 119) | void test_with_large_const_lvalue() {
function test_with_const_extra_large_obj (line 130) | void test_with_const_extra_large_obj() {
function test_with_const_big_array (line 136) | void test_with_const_big_array() {
function test_with_non_trivial_const_lvalue (line 142) | void test_with_non_trivial_const_lvalue() {
function test_div_by_two (line 150) | int test_div_by_two(int input) {
function test_inc_integer (line 160) | int test_inc_integer() {
function test_pointer_rvalue (line 174) | void test_pointer_rvalue() {
function test_pointer_const_lvalue (line 184) | void test_pointer_const_lvalue() {
function test_pointer_lvalue (line 195) | void test_pointer_lvalue() {
FILE: test/donotoptimize_test.cc
function double_up (line 10) | std::int64_t double_up(const std::int64_t x) { return x * 2; }
type BitRef (line 15) | struct BitRef {
method BitRef (line 20) | static BitRef Make() {
method BitRef (line 27) | BitRef(int i, unsigned char& b) : index(i), byte(b) {}
function main (line 30) | int main(int argc, char* argv[]) {
FILE: test/filter_test.cc
class TestReporter (line 18) | class TestReporter : public benchmark::ConsoleReporter {
method ReportContext (line 20) | bool ReportContext(const Context& context) override {
method ReportRuns (line 24) | void ReportRuns(const std::vector<Run>& report) override {
method TestReporter (line 30) | TestReporter() : count_(0), max_family_index_(0) {}
method GetCount (line 34) | int GetCount() const { return count_; }
method GetMaxFamilyIndex (line 36) | int64_t GetMaxFamilyIndex() const { return max_family_index_; }
function NoPrefix (line 43) | void NoPrefix(benchmark::State& state) {
function BM_Foo (line 49) | void BM_Foo(benchmark::State& state) {
function BM_Bar (line 55) | void BM_Bar(benchmark::State& state) {
function BM_FooBar (line 61) | void BM_FooBar(benchmark::State& state) {
function BM_FooBa (line 67) | void BM_FooBa(benchmark::State& state) {
function main (line 74) | int main(int argc, char** argv) {
FILE: test/fixture_test.cc
class FIXTURE_BECHMARK_NAME (line 11) | class FIXTURE_BECHMARK_NAME : public ::benchmark::Fixture {
method SetUp (line 13) | void SetUp(const ::benchmark::State& state) override {
method TearDown (line 20) | void TearDown(const ::benchmark::State& state) override {
FILE: test/internal_threading_test.cc
function MyBusySpinwait (line 21) | void MyBusySpinwait() {
function BM_MainThread (line 42) | void BM_MainThread(benchmark::State& state) {
function BM_WorkerThread (line 84) | void BM_WorkerThread(benchmark::State& state) {
function BM_MainThreadAndWorkerThread (line 127) | void BM_MainThreadAndWorkerThread(benchmark::State& state) {
function main (line 191) | int main(int argc, char* argv[]) {
FILE: test/link_main_test.cc
function BM_empty (line 6) | void BM_empty(benchmark::State& state) {
FILE: test/locale_impermeability_test.cc
function BM_ostream (line 12) | void BM_ostream(benchmark::State& state) {
function main (line 46) | int main(int argc, char* argv[]) {
FILE: test/manual_threading_test.cc
function MyBusySpinwait (line 22) | void MyBusySpinwait() {
class ManualThreadRunner (line 38) | class ManualThreadRunner : public benchmark::ThreadRunnerBase {
method ManualThreadRunner (line 40) | explicit ManualThreadRunner(int num_threads)
method RunThreads (line 43) | void RunThreads(const std::function<void(int)>& fn) final {
function BM_ManualThreading (line 69) | void BM_ManualThreading(benchmark::State& state) {
function main (line 172) | int main(int argc, char* argv[]) {
FILE: test/map_test.cc
function ConstructRandomMap (line 11) | std::map<int, int> ConstructRandomMap(int size) {
function BM_MapLookup (line 20) | void BM_MapLookup(benchmark::State& state) {
class MapFixture (line 38) | class MapFixture : public ::benchmark::Fixture {
method SetUp (line 40) | void SetUp(const ::benchmark::State& st) override {
method TearDown (line 44) | void TearDown(const ::benchmark::State& /*unused*/) override { m.clear...
FILE: test/memory_manager_test.cc
class TestMemoryManager (line 11) | class TestMemoryManager : public benchmark::MemoryManager {
method Start (line 12) | void Start() override {}
method Stop (line 13) | void Stop(Result& result) override {
function BM_empty (line 19) | void BM_empty(benchmark::State& state) {
function main (line 47) | int main(int argc, char* argv[]) {
FILE: test/memory_results_gtest.cc
function reset (line 27) | void reset() {
class TestMemoryManager (line 33) | class TestMemoryManager : public MemoryManager {
method Start (line 34) | void Start() override {}
method Stop (line 35) | void Stop(Result& result) override {
class TestReporter (line 48) | class TestReporter : public ConsoleReporter {
method TestReporter (line 50) | TestReporter() = default;
method ReportContext (line 53) | bool ReportContext(const Context& /*unused*/) override { return true; }
method PrintHeader (line 55) | void PrintHeader(const Run&) override {}
method PrintRunData (line 56) | void PrintRunData(const Run& run) override {
class MemoryResultsTest (line 66) | class MemoryResultsTest : public testing::Test {
method SetUp (line 71) | void SetUp() override {
method TearDown (line 80) | void TearDown() override { ClearRegisteredBenchmarks(); }
function TEST_F (line 83) | TEST_F(MemoryResultsTest, NoMMTest) {
function TEST_F (line 88) | TEST_F(MemoryResultsTest, ResultsTest) {
FILE: test/min_time_parse_gtest.cc
function TEST (line 6) | TEST(ParseMinTimeTest, InvalidInput) {
FILE: test/multiple_ranges_test.cc
class MultipleRangesFixture (line 12) | class MultipleRangesFixture : public ::benchmark::Fixture {
method MultipleRangesFixture (line 14) | MultipleRangesFixture()
method SetUp (line 35) | void SetUp(const ::benchmark::State& state) override {
function BM_CheckDefaultArgument (line 85) | void BM_CheckDefaultArgument(benchmark::State& state) {
function BM_MultipleRanges (line 94) | void BM_MultipleRanges(benchmark::State& st) {
FILE: test/options_test.cc
function BM_basic (line 15) | void BM_basic(benchmark::State& state) {
function BM_basic_slow (line 20) | void BM_basic_slow(benchmark::State& state) {
function CustomArgs (line 57) | void CustomArgs(benchmark::Benchmark* b) {
function BM_explicit_iteration_count (line 65) | void BM_explicit_iteration_count(benchmark::State& state) {
FILE: test/output_test.h
type MatchRules (line 25) | enum MatchRules : uint8_t {
type TestCase (line 32) | struct TestCase {
type TestCaseID (line 41) | enum TestCaseID : uint8_t {
type Results (line 87) | struct Results
type std (line 88) | typedef std::function<void(Results const&)> ResultsCheckFn;
function NumThreads (line 94) | struct Results {
function std (line 122) | const std::string* Get(const std::string& entry_name) const {
FILE: test/output_test_helper.cc
type internal (line 20) | namespace internal {
function TestCaseList (line 32) | TestCaseList& GetTestCaseList(TestCaseID ID) {
function SubMap (line 39) | SubMap& GetSubstitutions() {
function PerformSubstitutions (line 82) | std::string PerformSubstitutions(std::string source) {
function CheckCase (line 96) | void CheckCase(std::stringstream& remaining_output, TestCase const& TC,
function CheckCases (line 131) | void CheckCases(TestCaseList const& checks, std::stringstream& output) {
class TestReporter (line 144) | class TestReporter : public benchmark::BenchmarkReporter {
method TestReporter (line 146) | TestReporter(std::vector<benchmark::BenchmarkReporter*> reps)
method ReportContext (line 149) | bool ReportContext(const Context& context) override {
method ReportRuns (line 163) | void ReportRuns(const std::vector<Run>& report) override {
method Finalize (line 168) | void Finalize() override {
class ResultsChecker (line 189) | class ResultsChecker {
type PatternAndFn (line 191) | struct PatternAndFn : public TestCase { // reusing TestCase for its...
method PatternAndFn (line 192) | PatternAndFn(const std::string& rx, ResultsCheckFn fn_)
function ResultsChecker (line 215) | ResultsChecker& GetResultsChecker() {
type PatternAndFn (line 191) | struct PatternAndFn : public TestCase { // reusing TestCase for its...
method PatternAndFn (line 192) | PatternAndFn(const std::string& rx, ResultsCheckFn fn_)
type internal (line 185) | namespace internal {
function TestCaseList (line 32) | TestCaseList& GetTestCaseList(TestCaseID ID) {
function SubMap (line 39) | SubMap& GetSubstitutions() {
function PerformSubstitutions (line 82) | std::string PerformSubstitutions(std::string source) {
function CheckCase (line 96) | void CheckCase(std::stringstream& remaining_output, TestCase const& TC,
function CheckCases (line 131) | void CheckCases(TestCaseList const& checks, std::stringstream& output) {
class TestReporter (line 144) | class TestReporter : public benchmark::BenchmarkReporter {
method TestReporter (line 146) | TestReporter(std::vector<benchmark::BenchmarkReporter*> reps)
method ReportContext (line 149) | bool ReportContext(const Context& context) override {
method ReportRuns (line 163) | void ReportRuns(const std::vector<Run>& report) override {
method Finalize (line 168) | void Finalize() override {
class ResultsChecker (line 189) | class ResultsChecker {
type PatternAndFn (line 191) | struct PatternAndFn : public TestCase { // reusing TestCase for its...
method PatternAndFn (line 192) | PatternAndFn(const std::string& rx, ResultsCheckFn fn_)
function ResultsChecker (line 215) | ResultsChecker& GetResultsChecker() {
type PatternAndFn (line 191) | struct PatternAndFn : public TestCase { // reusing TestCase for its...
method PatternAndFn (line 192) | PatternAndFn(const std::string& rx, ResultsCheckFn fn_)
function AddChecker (line 330) | size_t AddChecker(const std::string& bm_name, const ResultsCheckFn& fn) {
function AddCases (line 391) | int AddCases(TestCaseID ID, std::initializer_list<TestCase> il) {
function SetSubstitutions (line 397) | int SetSubstitutions(
function BENCHMARK_DISABLE_DEPRECATED_WARNING (line 419) | BENCHMARK_DISABLE_DEPRECATED_WARNING
function BENCHMARK_RESTORE_DEPRECATED_WARNING (line 480) | BENCHMARK_RESTORE_DEPRECATED_WARNING
function ToHex (line 495) | char ToHex(int ch) {
function RandomHexChar (line 500) | char RandomHexChar() {
function GetRandomFileName (line 506) | std::string GetRandomFileName() {
function FileExists (line 516) | bool FileExists(std::string const& name) {
function GetTempFileName (line 521) | std::string GetTempFileName() {
function GetFileReporterOutput (line 538) | std::string GetFileReporterOutput(int argc, char* argv[]) {
FILE: test/overload_test.cc
function BENCHMARK_UNUSED (line 9) | BENCHMARK_UNUSED void MyOverloadedBenchmark() {}
function MyOverloadedBenchmark (line 13) | void MyOverloadedBenchmark(benchmark::State& state) {
function MyTemplatedOverloadedBenchmark (line 26) | void MyTemplatedOverloadedBenchmark() {}
function MyTemplatedOverloadedBenchmark (line 29) | void MyTemplatedOverloadedBenchmark(benchmark::State& state) {
FILE: test/perf_counters_gtest.cc
type MsgHandler (line 9) | struct MsgHandler {
function TEST (line 26) | TEST(PerfCountersTest, Init) {
function UniqueCounterNames (line 34) | static std::set<std::string> UniqueCounterNames(const PerfCounters& pc) {
function TEST (line 39) | TEST(PerfCountersTest, OneCounter) {
function TEST (line 48) | TEST(PerfCountersTest, NegativeTest) {
function SnapshotAndCombine (line 98) | static std::map<std::string, uint64_t> SnapshotAndCombine(
function TEST (line 111) | TEST(PerfCountersTest, Read1Counter) {
function TEST (line 126) | TEST(PerfCountersTest, Read1CounterEachCPU) {
function TEST (line 163) | TEST(PerfCountersTest, Read2Counters) {
function TEST (line 183) | TEST(PerfCountersTest, ReopenExistingCounters) {
function TEST (line 200) | TEST(PerfCountersTest, CreateExistingMeasurements) {
function BENCHMARK_DONT_OPTIMIZE (line 269) | BENCHMARK_DONT_OPTIMIZE size_t do_work() {
function measure (line 281) | void measure(size_t threadcount, std::map<std::string, uint64_t>* before,
function TEST (line 305) | TEST(PerfCountersTest, MultiThreaded) {
function TEST (line 342) | TEST(PerfCountersTest, HardwareLimits) {
FILE: test/perf_counters_test.cc
type benchmark (line 12) | namespace benchmark {
function BM_Simple (line 19) | void BM_Simple(benchmark::State& state) {
function BM_WithoutPauseResume (line 30) | void BM_WithoutPauseResume(benchmark::State& state) {
function BM_WithPauseResume (line 44) | void BM_WithPauseResume(benchmark::State& state) {
function CheckSimple (line 66) | static void CheckSimple(Results const& e) {
function SaveInstrCountWithoutResume (line 73) | void SaveInstrCountWithoutResume(Results const& e) {
function SaveInstrCountWithResume (line 77) | void SaveInstrCountWithResume(Results const& e) {
function main (line 86) | int main(int argc, char* argv[]) {
FILE: test/profiler_manager_gtest.cc
class TestProfilerManager (line 11) | class TestProfilerManager : public benchmark::ProfilerManager {
method AfterSetupStart (line 13) | void AfterSetupStart() override { ++start_called; }
method BeforeTeardownStop (line 14) | void BeforeTeardownStop() override { ++stop_called; }
function BM_empty (line 20) | void BM_empty(benchmark::State& state) {
function TEST (line 28) | TEST(ProfilerManager, ReregisterManager) {
FILE: test/profiler_manager_iterations_test.cc
class TestProfilerManager (line 19) | class TestProfilerManager : public benchmark::ProfilerManager {
method AfterSetupStart (line 20) | void AfterSetupStart() override { iteration_count = 0; }
method BeforeTeardownStop (line 21) | void BeforeTeardownStop() override {
class NullReporter (line 26) | class NullReporter : public benchmark::BenchmarkReporter {
method ReportContext (line 28) | bool ReportContext(const Context& /*context*/) override { return true; }
method ReportRuns (line 29) | void ReportRuns(const std::vector<Run>& /* report */) override {}
function BM_MyBench (line 32) | void BM_MyBench(benchmark::State& state) {
function main (line 40) | int main(int argc, char** argv) {
FILE: test/profiler_manager_test.cc
class TestProfilerManager (line 14) | class TestProfilerManager : public benchmark::ProfilerManager {
method AfterSetupStart (line 16) | void AfterSetupStart() override { ++start_called; }
method BeforeTeardownStop (line 17) | void BeforeTeardownStop() override { ++stop_called; }
function BM_empty (line 23) | void BM_empty(benchmark::State& state) {
function main (line 48) | int main(int argc, char* argv[]) {
FILE: test/register_benchmark_test.cc
class TestReporter (line 14) | class TestReporter : public benchmark::ConsoleReporter {
method ReportRuns (line 16) | void ReportRuns(const std::vector<Run>& report) override {
type TestCase (line 24) | struct TestCase {
method TestCase (line 28) | TestCase(const std::string& xname) : TestCase(xname, "") {}
method TestCase (line 29) | TestCase(const std::string& xname, const std::string& xlabel)
method CheckRun (line 34) | void CheckRun(Run const& run) const {
function AddCases (line 50) | int AddCases(std::initializer_list<TestCase> const& v) {
function BM_function (line 67) | void BM_function(benchmark::State& state) {
function BM_extra_args (line 82) | void BM_extra_args(benchmark::State& st, const char* label) {
function RegisterFromFunction (line 87) | int RegisterFromFunction() {
function DISABLED_BM_function (line 101) | void DISABLED_BM_function(benchmark::State& state) {
function BM_named (line 114) | void BM_named(benchmark::State& state) {
type CustomFixture (line 128) | struct CustomFixture {
function TestRegistrationAtRuntime (line 135) | void TestRegistrationAtRuntime() {
function RunTestOne (line 155) | void RunTestOne() {
function RunTestTwo (line 175) | void RunTestTwo() {
function main (line 202) | int main(int argc, char* argv[]) {
FILE: test/repetitions_test.cc
function BM_ExplicitRepetitions (line 12) | void BM_ExplicitRepetitions(benchmark::State& state) {
function BM_ImplicitRepetitions (line 114) | void BM_ImplicitRepetitions(benchmark::State& state) {
function main (line 218) | int main(int argc, char* argv[]) {
FILE: test/report_aggregates_only_test.cc
function BM_SummaryRepeat (line 16) | void BM_SummaryRepeat(benchmark::State& state) {
function main (line 23) | int main(int argc, char* argv[]) {
FILE: test/reporter_output_test.cc
function AddContextCases (line 20) | int AddContextCases() {
function BM_basic (line 74) | void BM_basic(benchmark::State& state) {
function BM_bytes_per_second (line 100) | void BM_bytes_per_second(benchmark::State& state) {
function BM_items_per_second (line 133) | void BM_items_per_second(benchmark::State& state) {
function BM_label (line 166) | void BM_label(benchmark::State& state) {
function BM_time_label_nanosecond (line 195) | void BM_time_label_nanosecond(benchmark::State& state) {
function BM_time_label_microsecond (line 218) | void BM_time_label_microsecond(benchmark::State& state) {
function BM_time_label_millisecond (line 241) | void BM_time_label_millisecond(benchmark::State& state) {
function BM_time_label_second (line 264) | void BM_time_label_second(benchmark::State& state) {
function BM_error (line 290) | void BM_error(benchmark::State& state) {
function BM_no_arg_name (line 315) | void BM_no_arg_name(benchmark::State& state) {
function BM_arg_name (line 335) | void BM_arg_name(benchmark::State& state) {
function BM_arg_names (line 355) | void BM_arg_names(benchmark::State& state) {
function BM_name (line 377) | void BM_name(benchmark::State& state) {
function BM_BigArgs (line 403) | void BM_BigArgs(benchmark::State& state) {
function BM_Complexity_O1 (line 415) | void BM_Complexity_O1(benchmark::State& state) {
function BM_Repeat (line 435) | void BM_Repeat(benchmark::State& state) {
function BM_RepeatOnce (line 649) | void BM_RepeatOnce(benchmark::State& state) {
function BM_SummaryRepeat (line 666) | void BM_SummaryRepeat(benchmark::State& state) {
function BM_SummaryDisplay (line 717) | void BM_SummaryDisplay(benchmark::State& state) {
function BM_RepeatTimeUnit (line 767) | void BM_RepeatTimeUnit(benchmark::State& state) {
function BM_UserStats (line 831) | void BM_UserStats(benchmark::State& state) {
function BM_UserPercentStats (line 962) | void BM_UserPercentStats(benchmark::State& state) {
function BM_JSON_Format (line 1107) | void BM_JSON_Format(benchmark::State& state) {
function BM_CSV_Format (line 1128) | void BM_CSV_Format(benchmark::State& state) {
function main (line 1141) | int main(int argc, char* argv[]) {
FILE: test/skip_with_error_test.cc
class TestReporter (line 15) | class TestReporter : public benchmark::ConsoleReporter {
method ReportContext (line 17) | bool ReportContext(const Context& context) override {
method ReportRuns (line 21) | void ReportRuns(const std::vector<Run>& report) override {
method TestReporter (line 26) | TestReporter() {}
type TestCase (line 32) | struct TestCase {
method CheckRun (line 39) | void CheckRun(Run const& run) const {
function AddCases (line 56) | int AddCases(const std::string& base_name,
function BM_error_no_running (line 69) | void BM_error_no_running(benchmark::State& state) {
function BM_error_before_running (line 75) | void BM_error_before_running(benchmark::State& state) {
function BM_error_before_running_batch (line 84) | void BM_error_before_running_batch(benchmark::State& state) {
function BM_error_before_running_range_for (line 93) | void BM_error_before_running_range_for(benchmark::State& state) {
function BM_error_during_running (line 102) | void BM_error_during_running(benchmark::State& state) {
function BM_error_during_running_ranged_for (line 125) | void BM_error_during_running_ranged_for(benchmark::State& state) {
function BM_error_after_running (line 147) | void BM_error_after_running(benchmark::State& state) {
function BM_error_while_paused (line 163) | void BM_error_while_paused(benchmark::State& state) {
function BM_malformed (line 187) | void BM_malformed(benchmark::State& /*unused*/) {
function main (line 197) | int main(int argc, char* argv[]) {
FILE: test/spec_arg_test.cc
class TestReporter (line 21) | class TestReporter : public benchmark::ConsoleReporter {
method ReportContext (line 23) | bool ReportContext(const Context& context) override {
method ReportRuns (line 27) | void ReportRuns(const std::vector<Run>& report) override {
method TestReporter (line 33) | TestReporter() {}
function BM_NotChosen (line 45) | void BM_NotChosen(benchmark::State& state) {
function BM_Chosen (line 52) | void BM_Chosen(benchmark::State& state) {
function main (line 60) | int main(int argc, char** argv) {
FILE: test/spec_arg_verbosity_test.cc
function BM_Verbosity (line 11) | void BM_Verbosity(benchmark::State& state) {
function main (line 18) | int main(int argc, char** argv) {
FILE: test/state_assembly_test.cc
function test_for_auto_loop (line 20) | int test_for_auto_loop() {
function test_while_loop (line 43) | int test_while_loop() {
FILE: test/statistics_gtest.cc
function TEST (line 9) | TEST(StatisticsTest, Mean) {
function TEST (line 15) | TEST(StatisticsTest, Median) {
function TEST (line 21) | TEST(StatisticsTest, StdDev) {
function TEST (line 28) | TEST(StatisticsTest, CV) {
FILE: test/string_util_gtest.cc
function TEST (line 13) | TEST(StringUtilTest, stoul) {
function TEST (line 76) | TEST(StringUtilTest, stoi) {
function TEST (line 125) | TEST(StringUtilTest, stod) {
function TEST (line 160) | TEST(StringUtilTest, StrSplit) {
function TEST_P (line 197) | TEST_P(HumanReadableFixture, HumanReadableNumber) {
FILE: test/templated_fixture_method_test.cc
class MyFixture (line 10) | class MyFixture : public ::benchmark::Fixture {
method MyFixture (line 12) | MyFixture() : data(0) {}
FILE: test/templated_fixture_test.cc
class MyFixture (line 10) | class MyFixture : public ::benchmark::Fixture {
method MyFixture (line 12) | MyFixture() : data(0) {}
FILE: test/time_unit_gtest.cc
type benchmark (line 5) | namespace benchmark {
type internal (line 6) | namespace internal {
class DummyBenchmark (line 10) | class DummyBenchmark : public benchmark::Benchmark {
method DummyBenchmark (line 12) | DummyBenchmark() : Benchmark("dummy") {}
method Run (line 13) | void Run(State& /*state*/) override {}
function TEST (line 16) | TEST(DefaultTimeUnitTest, TimeUnitIsNotSet) {
function TEST (line 21) | TEST(DefaultTimeUnitTest, DefaultIsSet) {
function TEST (line 28) | TEST(DefaultTimeUnitTest, DefaultAndExplicitUnitIsSet) {
FILE: test/user_counters_tabular_test.cc
function BM_Counters_Tabular (line 69) | void BM_Counters_Tabular(benchmark::State& state) {
function CheckTabular (line 364) | void CheckTabular(Results const& e) {
function BM_CounterRates_Tabular (line 381) | void BM_CounterRates_Tabular(benchmark::State& state) {
function CheckTabularRate (line 424) | void CheckTabularRate(Results const& e) {
function BM_CounterSet0_Tabular (line 441) | void BM_CounterSet0_Tabular(benchmark::State& state) {
function CheckSet0 (line 473) | void CheckSet0(Results const& e) {
function BM_CounterSet1_Tabular (line 481) | void BM_CounterSet1_Tabular(benchmark::State& state) {
function CheckSet1 (line 513) | void CheckSet1(Results const& e) {
function BM_CounterSet2_Tabular (line 525) | void BM_CounterSet2_Tabular(benchmark::State& state) {
function CheckSet2 (line 557) | void CheckSet2(Results const& e) {
function main (line 569) | int main(int argc, char* argv[]) {
FILE: test/user_counters_test.cc
function BM_Counters_Simple (line 29) | void BM_Counters_Simple(benchmark::State& state) {
function CheckSimple (line 56) | void CheckSimple(Results const& e) {
function BM_Counters_WithBytesAndItemsPSec (line 71) | void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) {
function CheckBytesAndItemsPSec (line 109) | void CheckBytesAndItemsPSec(Results const& e) {
function BM_Counters_Rate (line 125) | void BM_Counters_Rate(benchmark::State& state) {
function CheckRate (line 158) | void CheckRate(Results const& e) {
function BM_Invert (line 172) | void BM_Invert(benchmark::State& state) {
function CheckInvert (line 204) | void CheckInvert(Results const& e) {
function BM_Counters_InvertedRate (line 216) | void BM_Counters_InvertedRate(benchmark::State& state) {
function CheckInvertedRate (line 252) | void CheckInvertedRate(Results const& e) {
function BM_Counters_Threads (line 266) | void BM_Counters_Threads(benchmark::State& state) {
function CheckThreads (line 296) | void CheckThreads(Results const& e) {
function BM_Counters_AvgThreads (line 308) | void BM_Counters_AvgThreads(benchmark::State& state) {
function CheckAvgThreads (line 339) | void CheckAvgThreads(Results const& e) {
function BM_Counters_AvgThreadsRate (line 352) | void BM_Counters_AvgThreadsRate(benchmark::State& state) {
function CheckAvgThreadsRate (line 387) | void CheckAvgThreadsRate(Results const& e) {
function BM_Counters_IterationInvariant (line 402) | void BM_Counters_IterationInvariant(benchmark::State& state) {
function CheckIterationInvariant (line 432) | void CheckIterationInvariant(Results const& e) {
function BM_Counters_kIsIterationInvariantRate (line 447) | void BM_Counters_kIsIterationInvariantRate(benchmark::State& state) {
function CheckIsIterationInvariantRate (line 484) | void CheckIsIterationInvariantRate(Results const& e) {
function BM_Counters_AvgIterations (line 500) | void BM_Counters_AvgIterations(benchmark::State& state) {
function CheckAvgIterations (line 530) | void CheckAvgIterations(Results const& e) {
function BM_Counters_kAvgIterationsRate (line 544) | void BM_Counters_kAvgIterationsRate(benchmark::State& state) {
function CheckAvgIterationsRate (line 579) | void CheckAvgIterationsRate(Results const& e) {
function main (line 594) | int main(int argc, char* argv[]) {
FILE: test/user_counters_thousands_test.cc
function BM_Counters_Thousands (line 15) | void BM_Counters_Thousands(benchmark::State& state) {
function CheckThousands (line 172) | void CheckThousands(Results const& e) {
function main (line 192) | int main(int argc, char* argv[]) {
FILE: test/user_counters_threads_test.cc
function BM_Counters_Simple (line 29) | void BM_Counters_Simple(benchmark::State& state) {
function CheckSimple (line 59) | void CheckSimple(Results const& e) {
function BM_Counters_WithBytesAndItemsPSec (line 73) | void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) {
function CheckBytesAndItemsPSec (line 112) | void CheckBytesAndItemsPSec(Results const& e) {
function BM_Counters_Rate (line 130) | void BM_Counters_Rate(benchmark::State& state) {
function CheckRate (line 164) | void CheckRate(Results const& e) {
function BM_Invert (line 179) | void BM_Invert(benchmark::State& state) {
function CheckInvert (line 213) | void CheckInvert(Results const& e) {
function BM_Counters_InvertedRate (line 227) | void BM_Counters_InvertedRate(benchmark::State& state) {
function CheckInvertedRate (line 265) | void CheckInvertedRate(Results const& e) {
function BM_Counters_Threads (line 281) | void BM_Counters_Threads(benchmark::State& state) {
function CheckThreads (line 311) | void CheckThreads(Results const& e) {
function BM_Counters_AvgThreads (line 323) | void BM_Counters_AvgThreads(benchmark::State& state) {
function CheckAvgThreads (line 354) | void CheckAvgThreads(Results const& e) {
function BM_Counters_AvgThreadsRate (line 367) | void BM_Counters_AvgThreadsRate(benchmark::State& state) {
function CheckAvgThreadsRate (line 402) | void CheckAvgThreadsRate(Results const& e) {
function BM_Counters_IterationInvariant (line 417) | void BM_Counters_IterationInvariant(benchmark::State& state) {
function CheckIterationInvariant (line 449) | void CheckIterationInvariant(Results const& e) {
function BM_Counters_kIsIterationInvariantRate (line 464) | void BM_Counters_kIsIterationInvariantRate(benchmark::State& state) {
function CheckIsIterationInvariantRate (line 505) | void CheckIsIterationInvariantRate(Results const& e) {
function BM_Counters_AvgIterations (line 522) | void BM_Counters_AvgIterations(benchmark::State& state) {
function CheckAvgIterations (line 554) | void CheckAvgIterations(Results const& e) {
function BM_Counters_kAvgIterationsRate (line 569) | void BM_Counters_kAvgIterationsRate(benchmark::State& state) {
function CheckAvgIterationsRate (line 606) | void CheckAvgIterationsRate(Results const& e) {
function main (line 622) | int main(int argc, char* argv[]) {
FILE: tools/compare.py
function check_inputs (line 20) | def check_inputs(in1, in2, flags):
function create_parser (line 59) | def create_parser():
function main (line 248) | def main():
class TestParser (line 354) | class TestParser(unittest.TestCase):
method setUp (line 355) | def setUp(self):
method test_benchmarks_basic (line 363) | def test_benchmarks_basic(self):
method test_benchmarks_basic_without_utest (line 374) | def test_benchmarks_basic_without_utest(self):
method test_benchmarks_basic_display_aggregates_only (line 386) | def test_benchmarks_basic_display_aggregates_only(self):
method test_benchmarks_basic_with_utest_alpha (line 397) | def test_benchmarks_basic_with_utest_alpha(self):
method test_benchmarks_basic_without_utest_with_utest_alpha (line 409) | def test_benchmarks_basic_without_utest_with_utest_alpha(self):
method test_benchmarks_with_remainder (line 427) | def test_benchmarks_with_remainder(self):
method test_benchmarks_with_remainder_after_doubleminus (line 438) | def test_benchmarks_with_remainder_after_doubleminus(self):
method test_filters_basic (line 449) | def test_filters_basic(self):
method test_filters_with_remainder (line 459) | def test_filters_with_remainder(self):
method test_filters_with_remainder_after_doubleminus (line 471) | def test_filters_with_remainder_after_doubleminus(self):
method test_benchmarksfiltered_basic (line 483) | def test_benchmarksfiltered_basic(self):
method test_benchmarksfiltered_with_remainder (line 496) | def test_benchmarksfiltered_with_remainder(self):
method test_benchmarksfiltered_with_remainder_after_doubleminus (line 516) | def test_benchmarksfiltered_with_remainder_after_doubleminus(self):
FILE: tools/gbench/report.py
class BenchmarkColor (line 17) | class BenchmarkColor:
method __init__ (line 18) | def __init__(self, name, code):
method __repr__ (line 22) | def __repr__(self):
method __format__ (line 25) | def __format__(self, format):
function color_format (line 55) | def color_format(use_color, fmt_str, *args, **kwargs):
function find_longest_name (line 75) | def find_longest_name(benchmark_list):
function calculate_change (line 87) | def calculate_change(old_val, new_val):
function filter_benchmark (line 98) | def filter_benchmark(json_orig, family, replacement=""):
function get_unique_benchmark_names (line 114) | def get_unique_benchmark_names(json):
function intersect (line 127) | def intersect(list1, list2):
function is_potentially_comparable_benchmark (line 135) | def is_potentially_comparable_benchmark(x):
function partition_benchmarks (line 139) | def partition_benchmarks(json1, json2):
function get_timedelta_field_as_seconds (line 175) | def get_timedelta_field_as_seconds(benchmark, field_name):
function calculate_geomean (line 185) | def calculate_geomean(json):
function extract_field (line 203) | def extract_field(partition, field_name):
function calc_utest (line 210) | def calc_utest(timings_cpu, timings_time):
function print_utest (line 232) | def print_utest(bc_name, utest, utest_alpha, first_col_width, use_color=...
function get_difference_report (line 277) | def get_difference_report(json1, json2, utest=False):
function print_difference_report (line 379) | def print_difference_report(
class TestGetUniqueBenchmarkNames (line 461) | class TestGetUniqueBenchmarkNames(unittest.TestCase):
method load_results (line 462) | def load_results(self):
method test_basic (line 473) | def test_basic(self):
class TestReportDifference (line 489) | class TestReportDifference(unittest.TestCase):
method setUpClass (line 491) | def setUpClass(cls):
method test_json_diff_report_pretty_printing (line 509) | def test_json_diff_report_pretty_printing(self):
method test_json_diff_report_output (line 594) | def test_json_diff_report_output(self):
class TestReportDifferenceBetweenFamilies (line 834) | class TestReportDifferenceBetweenFamilies(unittest.TestCase):
method setUpClass (line 836) | def setUpClass(cls):
method test_json_diff_report_pretty_printing (line 853) | def test_json_diff_report_pretty_printing(self):
method test_json_diff_report (line 873) | def test_json_diff_report(self):
class TestReportDifferenceWithUTest (line 963) | class TestReportDifferenceWithUTest(unittest.TestCase):
method setUpClass (line 965) | def setUpClass(cls):
method test_json_diff_report_pretty_printing (line 983) | def test_json_diff_report_pretty_printing(self):
method test_json_diff_report_pretty_printing_aggregates_only (line 1038) | def test_json_diff_report_pretty_printing_aggregates_only(self):
method test_json_diff_report (line 1094) | def test_json_diff_report(self):
class TestReportDifferenceWithUTestWhileDisplayingAggregatesOnly (line 1208) | class TestReportDifferenceWithUTestWhileDisplayingAggregatesOnly(
method setUpClass (line 1212) | def setUpClass(cls):
method test_json_diff_report_pretty_printing (line 1230) | def test_json_diff_report_pretty_printing(self):
method test_json_diff_report (line 1285) | def test_json_diff_report(self):
class TestReportDifferenceForPercentageAggregates (line 1400) | class TestReportDifferenceForPercentageAggregates(unittest.TestCase):
method setUpClass (line 1402) | def setUpClass(cls):
method test_json_diff_report_pretty_printing (line 1420) | def test_json_diff_report_pretty_printing(self):
method test_json_diff_report (line 1433) | def test_json_diff_report(self):
class TestReportSorting (line 1461) | class TestReportSorting(unittest.TestCase):
method setUpClass (line 1463) | def setUpClass(cls):
method test_json_diff_report_pretty_printing (line 1477) | def test_json_diff_report_pretty_printing(self):
class TestReportDifferenceWithUTestWhileDisplayingAggregatesOnly2 (line 1507) | class TestReportDifferenceWithUTestWhileDisplayingAggregatesOnly2(
method setUpClass (line 1511) | def setUpClass(cls):
method test_json_diff_report_pretty_printing (line 1535) | def test_json_diff_report_pretty_printing(self):
method test_json_diff_report (line 1559) | def test_json_diff_report(self):
function assert_utest (line 1603) | def assert_utest(unittest_instance, lhs, rhs):
function assert_measurements (line 1620) | def assert_measurements(unittest_instance, lhs, rhs):
FILE: tools/gbench/util.py
function is_executable_file (line 20) | def is_executable_file(filename):
function is_json_file (line 45) | def is_json_file(filename):
function classify_input_file (line 59) | def classify_input_file(filename):
function check_input_file (line 83) | def check_input_file(filename):
function find_benchmark_flag (line 96) | def find_benchmark_flag(prefix, benchmark_flags):
function remove_benchmark_flags (line 111) | def remove_benchmark_flags(prefix, benchmark_flags):
function load_benchmark_results (line 121) | def load_benchmark_results(fname, benchmark_filter):
function sort_benchmark_results (line 157) | def sort_benchmark_results(result):
function run_benchmark (line 184) | def run_benchmark(exe_name, benchmark_flags):
function run_or_load_benchmark (line 214) | def run_or_load_benchmark(filename, benchmark_flags):
FILE: tools/strip_asm.py
function find_used_labels (line 13) | def find_used_labels(asm):
function normalize_labels (line 23) | def normalize_labels(asm):
function transform_labels (line 40) | def transform_labels(asm):
function is_identifier (line 53) | def is_identifier(tk):
function process_identifiers (line 66) | def process_identifiers(line):
function process_asm (line 90) | def process_asm(asm):
function main (line 132) | def main():
Condensed preview — 203 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,072K chars).
[
{
"path": ".bazelversion",
"chars": 6,
"preview": "8.2.1\n"
},
{
"path": ".clang-format",
"chars": 74,
"preview": "---\nLanguage: Cpp\nBasedOnStyle: Google\nPointerAlignment: Left\n...\n"
},
{
"path": ".clang-tidy",
"chars": 3220,
"preview": "---\nChecks: >\n abseil-*,\n bugprone-*,\n clang-analyzer-*,\n cppcoreguidelines-*,\n google-*,\n misc-*,\n performance-*"
},
{
"path": ".clang-tidy.ignore",
"chars": 17,
"preview": ".*third_party/.*\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 637,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: \"[BUG]\"\nlabels: ''\nassignees: ''\n\n---\n\n**Describe "
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 599,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: \"[FR]\"\nlabels: ''\nassignees: ''\n\n---\n\n**Is your"
},
{
"path": ".github/dependabot.yml",
"chars": 197,
"preview": "version: 2\nupdates:\n - package-ecosystem: github-actions\n directory: /\n schedule:\n interval: daily\n\n - pack"
},
{
"path": ".github/install_bazel.sh",
"chars": 389,
"preview": "if ! bazel version; then\n arch=$(uname -m)\n if [ \"$arch\" == \"aarch64\" ]; then\n arch=\"arm64\"\n fi\n echo \"Downloadin"
},
{
"path": ".github/libcxx-setup.sh",
"chars": 1281,
"preview": "#!/usr/bin/env bash\n\nset -e\n\n# Checkout LLVM sources\ngit clone --filter=blob:none --depth=1 --branch llvmorg-19.1.6 --no"
},
{
"path": ".github/workflows/bazel.yml",
"chars": 918,
"preview": "name: bazel\n\non:\n push: {}\n pull_request: {}\n\nenv:\n CMAKE_GENERATOR: Ninja\n\npermissions:\n contents: read\n\njobs:\n bu"
},
{
"path": ".github/workflows/build-and-test-min-cmake.yml",
"chars": 1255,
"preview": "name: build-and-test-min-cmake\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\nenv:\n CMAKE_"
},
{
"path": ".github/workflows/build-and-test-perfcounters.yml",
"chars": 1552,
"preview": "name: build-and-test-perfcounters\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\nenv:\n CMA"
},
{
"path": ".github/workflows/build-and-test.yml",
"chars": 4535,
"preview": "name: build-and-test\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\nenv:\n CMAKE_GENERATOR:"
},
{
"path": ".github/workflows/clang-format-lint.yml",
"chars": 479,
"preview": "name: clang-format-lint\non:\n push: {}\n pull_request: {}\n\nenv:\n CMAKE_GENERATOR: Ninja\n\npermissions:\n contents: read\n"
},
{
"path": ".github/workflows/clang-tidy-lint.yml",
"chars": 1091,
"preview": "name: clang-tidy\n\non:\n push: {}\n pull_request: {}\n\nenv:\n CMAKE_GENERATOR: Ninja\n\npermissions:\n contents: read\n\njobs:"
},
{
"path": ".github/workflows/doxygen.yml",
"chars": 791,
"preview": "name: doxygen\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\nenv:\n CMAKE_GENERATOR: Ninja\n\nper"
},
{
"path": ".github/workflows/ossf.yml",
"chars": 639,
"preview": "name: OSSF Scorecard Weekly\n\non:\n schedule:\n - cron: '0 0 * * 0' # Runs every Sunday at midnight UTC\n workflow_disp"
},
{
"path": ".github/workflows/pre-commit.yml",
"chars": 574,
"preview": "name: python + Bazel pre-commit checks\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\njobs:"
},
{
"path": ".github/workflows/sanitizer.yml",
"chars": 3361,
"preview": "name: sanitizer\n\non:\n push: {}\n pull_request: {}\n\nenv:\n CMAKE_GENERATOR: Ninja\n UBSAN_OPTIONS: \"print_stacktrace=1\"\n"
},
{
"path": ".github/workflows/test_bindings.yml",
"chars": 1057,
"preview": "name: test-bindings\n\non:\n push:\n branches: [main]\n pull_request:\n branches: [main]\n\nenv:\n CMAKE_GENERATOR: Ninj"
},
{
"path": ".github/workflows/wheels.yml",
"chars": 2961,
"preview": "name: Build and upload Python wheels\n\non:\n workflow_dispatch:\n release:\n types:\n - published\n\nenv:\n CMAKE_GEN"
},
{
"path": ".gitignore",
"chars": 789,
"preview": "*.a\n*.so\n*.so.?*\n*.dll\n*.exe\n*.dylib\n*.cmake\n!/cmake/*.cmake\n!/test/AssemblyTests.cmake\n*~\n*.swp\n*.pyc\n__pycache__\n.DS_S"
},
{
"path": ".pre-commit-config.yaml",
"chars": 531,
"preview": "repos:\n - repo: https://github.com/keith/pre-commit-buildifier\n rev: 8.2.1\n hooks:\n - id: buildifier"
},
{
"path": ".ycm_extra_conf.py",
"chars": 3920,
"preview": "import os\n\nimport ycm_core\n\n# These are the compilation flags that will be used in case there's no\n# compilation databas"
},
{
"path": "AUTHORS",
"chars": 2880,
"preview": "# This is the official list of benchmark authors for copyright purposes.\n# This file is distinct from the CONTRIBUTORS f"
},
{
"path": "BUILD.bazel",
"chars": 3353,
"preview": "load(\"@rules_cc//cc:defs.bzl\", \"cc_library\")\n\nlicenses([\"notice\"])\n\nCOPTS = [\n \"-pedantic\",\n \"-pedantic-errors\",\n "
},
{
"path": "CMakeLists.txt",
"chars": 14852,
"preview": "# Require CMake 3.10. If available, use the policies up to CMake 3.22.\ncmake_minimum_required (VERSION 3.13...3.22)\n\npro"
},
{
"path": "CONTRIBUTING.md",
"chars": 2485,
"preview": "# How to contribute #\n\nWe'd love to accept your patches and contributions to this project. There are\na just a few small"
},
{
"path": "CONTRIBUTORS",
"chars": 4177,
"preview": "# People who have agreed to one of the CLAs and can contribute patches.\n# The AUTHORS file lists the copyright holders; "
},
{
"path": "LICENSE",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "MODULE.bazel",
"chars": 1455,
"preview": "module(\n name = \"google_benchmark\",\n version = \"1.9.5\",\n)\n\nbazel_dep(name = \"bazel_skylib\", version = \"1.7.1\")\nbaz"
},
{
"path": "README.md",
"chars": 7975,
"preview": "# Benchmark\n\n[](https://github."
},
{
"path": "WORKSPACE",
"chars": 430,
"preview": "workspace(name = \"com_github_google_benchmark\")\n\nload(\"//:bazel/benchmark_deps.bzl\", \"benchmark_deps\")\n\nbenchmark_deps()"
},
{
"path": "WORKSPACE.bzlmod",
"chars": 98,
"preview": "# This file marks the root of the Bazel workspace.\n# See MODULE.bazel for dependencies and setup.\n"
},
{
"path": "_config.yml",
"chars": 43,
"preview": "theme: jekyll-theme-midnight\nmarkdown: GFM\n"
},
{
"path": "appveyor.yml",
"chars": 1266,
"preview": "version: '{build}'\n\nimage: Visual Studio 2017\n\nconfiguration:\n - Debug\n - Release\n\nenvironment:\n matrix:\n - compil"
},
{
"path": "bazel/benchmark_deps.bzl",
"chars": 2330,
"preview": "\"\"\"\nThis file contains the Bazel build dependencies for Google Benchmark (both C++ source and Python bindings).\n\"\"\"\n\nloa"
},
{
"path": "bindings/python/google_benchmark/BUILD",
"chars": 762,
"preview": "load(\"@nanobind_bazel//:build_defs.bzl\", \"nanobind_extension\", \"nanobind_stubgen\")\nload(\"@rules_python//python:defs.bzl\""
},
{
"path": "bindings/python/google_benchmark/__init__.py",
"chars": 4225,
"preview": "# Copyright 2020 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# "
},
{
"path": "bindings/python/google_benchmark/benchmark.cc",
"chars": 8053,
"preview": "// Benchmark for Python.\n\n#include \"benchmark/benchmark.h\"\n\n#include \"nanobind/nanobind.h\"\n#include \"nanobind/operators."
},
{
"path": "bindings/python/google_benchmark/example.py",
"chars": 3958,
"preview": "# Copyright 2020 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# "
},
{
"path": "cmake/AddCXXCompilerFlag.cmake",
"chars": 2969,
"preview": "# - Adds a compiler flag if it is supported by the compiler\n#\n# This function checks that the supplied compiler flag is "
},
{
"path": "cmake/CXXFeatureCheck.cmake",
"chars": 2791,
"preview": "# - Compile and run code to check for C++ features\n#\n# This functions compiles a source file under the `cmake` folder\n# "
},
{
"path": "cmake/Config.cmake.in",
"chars": 273,
"preview": "@PACKAGE_INIT@\n\ninclude (CMakeFindDependencyMacro)\n\nfind_dependency (Threads)\n\nif (@BENCHMARK_ENABLE_LIBPFM@)\n list(A"
},
{
"path": "cmake/GetGitVersion.cmake",
"chars": 859,
"preview": "# - Returns a version string from Git tags\n#\n# This function inspects the annotated git tags for the project and returns"
},
{
"path": "cmake/GoogleTest.cmake",
"chars": 2656,
"preview": "# Download and unpack googletest at configure time\nset(GOOGLETEST_PREFIX \"${benchmark_BINARY_DIR}/third_party/googletest"
},
{
"path": "cmake/GoogleTest.cmake.in",
"chars": 2688,
"preview": "cmake_minimum_required (VERSION 3.13...3.22)\n\nproject(googletest-download NONE)\n\n# Enable ExternalProject CMake module\ni"
},
{
"path": "cmake/benchmark.pc.in",
"chars": 341,
"preview": "prefix=@CMAKE_INSTALL_PREFIX@\nexec_prefix=${prefix}\nlibdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_IN"
},
{
"path": "cmake/benchmark_main.pc.in",
"chars": 210,
"preview": "libdir=@CMAKE_INSTALL_FULL_LIBDIR@\n\nName: @PROJECT_NAME@\nDescription: Google microbenchmark framework (with main() funct"
},
{
"path": "cmake/gnu_posix_regex.cpp",
"chars": 267,
"preview": "#include <gnuregex.h>\n#include <string>\nint main() {\n std::string str = \"test0159\";\n regex_t re;\n int ec = regcomp(&r"
},
{
"path": "cmake/llvm-toolchain.cmake",
"chars": 287,
"preview": "find_package(LLVMAr REQUIRED)\nset(CMAKE_AR \"${LLVMAR_EXECUTABLE}\" CACHE FILEPATH \"\" FORCE)\n\nfind_package(LLVMNm REQUIRED"
},
{
"path": "cmake/posix_regex.cpp",
"chars": 297,
"preview": "#include <regex.h>\n#include <string>\nint main() {\n std::string str = \"test0159\";\n regex_t re;\n int ec = regcomp(&re, "
},
{
"path": "cmake/pthread_affinity.cpp",
"chars": 439,
"preview": "#include <pthread.h>\n#ifdef __FreeBSD__\n#include <pthread_np.h>\n#endif\nint main() {\n cpu_set_t set;\n CPU_ZERO(&set);\n "
},
{
"path": "cmake/split_list.cmake",
"chars": 93,
"preview": "macro(split_list listname)\n string(REPLACE \";\" \" \" ${listname} \"${${listname}}\")\nendmacro()\n"
},
{
"path": "cmake/std_regex.cpp",
"chars": 259,
"preview": "#include <regex>\n#include <string>\nint main() {\n const std::string str = \"test0159\";\n std::regex re;\n re = std::regex"
},
{
"path": "cmake/steady_clock.cpp",
"chars": 136,
"preview": "#include <chrono>\n\nint main() {\n typedef std::chrono::steady_clock Clock;\n Clock::time_point tp = Clock::now();\n "
},
{
"path": "cmake/thread_safety_attributes.cpp",
"chars": 79,
"preview": "#define HAVE_THREAD_SAFETY_ATTRIBUTES\n#include \"../src/mutex.h\"\n\nint main() {}\n"
},
{
"path": "docs/AssemblyTests.md",
"chars": 5324,
"preview": "# Assembly Tests\n\nThe Benchmark library provides a number of functions whose primary\npurpose in to affect assembly gener"
},
{
"path": "docs/_config.yml",
"chars": 85,
"preview": "theme: jekyll-theme-minimal\nlogo: /assets/images/icon_black.png\nshow_downloads: true\n"
},
{
"path": "docs/dependencies.md",
"chars": 933,
"preview": "# Build tool dependency policy\n\nWe follow the [Foundational C++ support policy](https://opensource.google/documentation/"
},
{
"path": "docs/index.md",
"chars": 412,
"preview": "# Benchmark\n\n* [Assembly Tests](AssemblyTests.md)\n* [Dependencies](dependencies.md)\n* [Perf Counters](perf_counters.md)\n"
},
{
"path": "docs/perf_counters.md",
"chars": 1567,
"preview": "<a name=\"perf-counters\" />\n\n# User-Requested Performance Counters\n\nWhen running benchmarks, the user may choose to reque"
},
{
"path": "docs/platform_specific_build_instructions.md",
"chars": 2368,
"preview": "# Platform Specific Build Instructions\n\n## Building with GCC\n\nWhen the library is built using GCC it is necessary to lin"
},
{
"path": "docs/python_bindings.md",
"chars": 1405,
"preview": "# Building and installing Python bindings\n\nPython bindings are available as wheels on [PyPI](https://pypi.org/project/go"
},
{
"path": "docs/random_interleaving.md",
"chars": 647,
"preview": "<a name=\"interleaving\" />\n\n# Random Interleaving\n\n[Random Interleaving](https://github.com/google/benchmark/issues/1051)"
},
{
"path": "docs/reducing_variance.md",
"chars": 4779,
"preview": "# Reducing Variance\n\n<a name=\"disabling-cpu-frequency-scaling\" />\n\n## Disabling CPU Frequency Scaling\n\nIf you see this e"
},
{
"path": "docs/releasing.md",
"chars": 1260,
"preview": "# How to release\n\n* Make sure you're on main and synced to HEAD\n* Ensure the project builds and tests run\n * `paralle"
},
{
"path": "docs/tools.md",
"chars": 19211,
"preview": "# Benchmark Tools\n\n## compare.py\n\nThe `compare.py` can be used to compare the result of benchmarks.\n\n### Dependencies\nTh"
},
{
"path": "docs/user_guide.md",
"chars": 49480,
"preview": "# User Guide\n\n## Command Line\n\n[Output Formats](#output-formats)\n\n[Output Files](#output-files)\n\n[Running Benchmarks](#r"
},
{
"path": "include/benchmark/benchmark.h",
"chars": 1058,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/benchmark_api.h",
"chars": 9412,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/counter.h",
"chars": 2294,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/export.h",
"chars": 1481,
"preview": "#ifndef BENCHMARK_EXPORT_H\n#define BENCHMARK_EXPORT_H\n\n#if defined(_WIN32)\n#define EXPORT_ATTR __declspec(dllexport)\n#de"
},
{
"path": "include/benchmark/macros.h",
"chars": 4733,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/managers.h",
"chars": 1750,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/registration.h",
"chars": 13705,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/reporter.h",
"chars": 6469,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/state.h",
"chars": 6901,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/statistics.h",
"chars": 1755,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/sysinfo.h",
"chars": 1612,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/types.h",
"chars": 1387,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "include/benchmark/utils.h",
"chars": 4815,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "pyproject.toml",
"chars": 2074,
"preview": "[build-system]\nrequires = [\"setuptools\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"google_benchmark\"\nde"
},
{
"path": "setup.py",
"chars": 5922,
"preview": "import contextlib\nimport os\nimport platform\nimport re\nimport shutil\nimport sys\nfrom collections.abc import Generator\nfro"
},
{
"path": "src/CMakeLists.txt",
"chars": 6275,
"preview": "#Allow the source files to find headers in src /\ninclude(GNUInstallDirs)\ninclude_directories(${PROJECT_SOURCE_DIR}/src)\n"
},
{
"path": "src/arraysize.h",
"chars": 1108,
"preview": "#ifndef BENCHMARK_ARRAYSIZE_H_\n#define BENCHMARK_ARRAYSIZE_H_\n\n#include \"internal_macros.h\"\n\nnamespace benchmark {\nnames"
},
{
"path": "src/benchmark.cc",
"chars": 32296,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/benchmark_api_internal.cc",
"chars": 3699,
"preview": "#include \"benchmark_api_internal.h\"\n\n#include <cinttypes>\n\n#include \"string_util.h\"\n\nnamespace benchmark {\nnamespace int"
},
{
"path": "src/benchmark_api_internal.h",
"chars": 3070,
"preview": "#ifndef BENCHMARK_API_INTERNAL_H\n#define BENCHMARK_API_INTERNAL_H\n\n#include <cmath>\n#include <iosfwd>\n#include <limits>\n"
},
{
"path": "src/benchmark_main.cc",
"chars": 753,
"preview": "// Copyright 2018 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/benchmark_name.cc",
"chars": 1775,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/benchmark_register.cc",
"chars": 16277,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/benchmark_register.h",
"chars": 3051,
"preview": "#ifndef BENCHMARK_REGISTER_H\n#define BENCHMARK_REGISTER_H\n\n#include <algorithm>\n#include <limits>\n#include <type_traits>"
},
{
"path": "src/benchmark_runner.cc",
"chars": 21387,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/benchmark_runner.h",
"chars": 3450,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/check.cc",
"chars": 324,
"preview": "#include \"check.h\"\n\nnamespace benchmark {\nnamespace internal {\n\nnamespace {\n// NOLINTNEXTLINE(cppcoreguidelines-avoid-no"
},
{
"path": "src/check.h",
"chars": 3255,
"preview": "#ifndef CHECK_H_\n#define CHECK_H_\n\n#include <cmath>\n#include <cstdlib>\n#include <ostream>\n#include <string_view>\n\n#inclu"
},
{
"path": "src/colorprint.cc",
"chars": 5804,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/colorprint.h",
"chars": 918,
"preview": "#ifndef BENCHMARK_COLORPRINT_H_\n#define BENCHMARK_COLORPRINT_H_\n\n#include <cstdarg>\n#include <iostream>\n#include <string"
},
{
"path": "src/commandlineflags.cc",
"chars": 9966,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/commandlineflags.h",
"chars": 5308,
"preview": "#ifndef BENCHMARK_COMMANDLINEFLAGS_H_\n#define BENCHMARK_COMMANDLINEFLAGS_H_\n\n#include <cstdint>\n#include <map>\n#include "
},
{
"path": "src/complexity.cc",
"chars": 9050,
"preview": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/complexity.h",
"chars": 2013,
"preview": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "src/console_reporter.cc",
"chars": 7437,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/counter.cc",
"chars": 2246,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/counter.h",
"chars": 1129,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/csv_reporter.cc",
"chars": 4862,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/cycleclock.h",
"chars": 10978,
"preview": "// ----------------------------------------------------------------------\n// CycleClock\n// A CycleClock tells you the"
},
{
"path": "src/internal_macros.h",
"chars": 3321,
"preview": "#ifndef BENCHMARK_INTERNAL_MACROS_H_\n#define BENCHMARK_INTERNAL_MACROS_H_\n\n/* Needed to detect STL */\n#include <cstdlib>"
},
{
"path": "src/json_reporter.cc",
"chars": 10917,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/log.h",
"chars": 1810,
"preview": "#ifndef BENCHMARK_LOG_H_\n#define BENCHMARK_LOG_H_\n\n#include <iostream>\n#include <ostream>\n\nnamespace benchmark {\nnamespa"
},
{
"path": "src/mutex.h",
"chars": 4578,
"preview": "#ifndef BENCHMARK_MUTEX_H_\n#define BENCHMARK_MUTEX_H_\n\n#include <condition_variable>\n#include <mutex>\n\n#include \"check.h"
},
{
"path": "src/perf_counters.cc",
"chars": 11490,
"preview": "// Copyright 2021 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/perf_counters.h",
"chars": 6969,
"preview": "// Copyright 2021 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/re.h",
"chars": 3903,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/reporter.cc",
"chars": 4138,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/statistics.cc",
"chars": 7826,
"preview": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n// Copyright 2017 Roman Lebedev. All rights reserved.\n//"
},
{
"path": "src/statistics.h",
"chars": 1528,
"preview": "// Copyright 2016 Ismael Jimenez Martinez. All rights reserved.\n// Copyright 2017 Roman Lebedev. All rights reserved.\n//"
},
{
"path": "src/string_util.cc",
"chars": 8293,
"preview": "#include \"string_util.h\"\n\n#include <array>\n#ifdef BENCHMARK_STL_ANDROID_GNUSTL\n#include <cerrno>\n#endif\n#include <cmath>"
},
{
"path": "src/string_util.h",
"chars": 1854,
"preview": "#ifndef BENCHMARK_STRING_UTIL_H_\n#define BENCHMARK_STRING_UTIL_H_\n\n#include <sstream>\n#include <string>\n#include <utilit"
},
{
"path": "src/sysinfo.cc",
"chars": 27312,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/thread_manager.h",
"chars": 1150,
"preview": "#ifndef BENCHMARK_THREAD_MANAGER_H\n#define BENCHMARK_THREAD_MANAGER_H\n\n#include <atomic>\n\n#include \"benchmark/counter.h\""
},
{
"path": "src/thread_timer.h",
"chars": 2297,
"preview": "#ifndef BENCHMARK_THREAD_TIMER_H\n#define BENCHMARK_THREAD_TIMER_H\n\n#include \"check.h\"\n#include \"timers.h\"\n\nnamespace ben"
},
{
"path": "src/timers.cc",
"chars": 10764,
"preview": "// Copyright 2015 Google Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "src/timers.h",
"chars": 1970,
"preview": "#ifndef BENCHMARK_TIMERS_H\n#define BENCHMARK_TIMERS_H\n\n#include <chrono>\n#include <string>\n\nnamespace benchmark {\n\n// Re"
},
{
"path": "test/AssemblyTests.cmake",
"chars": 2308,
"preview": "set(CLANG_SUPPORTED_VERSION \"5.0.0\")\nset(GCC_SUPPORTED_VERSION \"5.5.0\")\n\nif (CMAKE_CXX_COMPILER_ID MATCHES \"Clang\")\n if"
},
{
"path": "test/BUILD",
"chars": 3451,
"preview": "load(\"@rules_cc//cc:defs.bzl\", \"cc_library\", \"cc_test\")\n\nplatform(\n name = \"windows\",\n constraint_values = [\n "
},
{
"path": "test/CMakeLists.txt",
"chars": 13734,
"preview": "#Enable the tests\n\nset(THREADS_PREFER_PTHREAD_FLAG ON)\n\nfind_package(Threads REQUIRED)\ninclude(CheckCXXCompilerFlag)\n\nad"
},
{
"path": "test/args_product_test.cc",
"chars": 2327,
"preview": "#include <cassert>\n#include <iostream>\n#include <set>\n#include <vector>\n\n#include \"benchmark/benchmark_api.h\"\n#include \""
},
{
"path": "test/basic_test.cc",
"chars": 5489,
"preview": "\n#include \"benchmark/registration.h\"\n#include \"benchmark/state.h\"\n#include \"benchmark/types.h\"\n#include \"benchmark/utils"
},
{
"path": "test/benchmark_gtest.cc",
"chars": 4997,
"preview": "#include <map>\n#include <string>\n#include <vector>\n\n#include \"../src/benchmark_register.h\"\n#include \"benchmark/benchmark"
},
{
"path": "test/benchmark_min_time_flag_iters_test.cc",
"chars": 1863,
"preview": "#include <cassert>\n#include <cstdlib>\n#include <cstring>\n#include <string>\n#include <vector>\n\n#include \"benchmark/benchm"
},
{
"path": "test/benchmark_min_time_flag_time_test.cc",
"chars": 2563,
"preview": "#include <cassert>\n#include <climits>\n#include <cmath>\n#include <cstdlib>\n#include <cstring>\n#include <iostream>\n#includ"
},
{
"path": "test/benchmark_name_gtest.cc",
"chars": 2361,
"preview": "#include \"benchmark/reporter.h\"\n#include \"gtest/gtest.h\"\n\nnamespace {\n\nusing namespace benchmark;\nusing namespace benchm"
},
{
"path": "test/benchmark_random_interleaving_gtest.cc",
"chars": 3627,
"preview": "#include <queue>\n#include <string>\n#include <vector>\n\n#include \"../src/commandlineflags.h\"\n#include \"../src/string_util."
},
{
"path": "test/benchmark_setup_teardown_cb_types_gtest.cc",
"chars": 3832,
"preview": "#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/reporter.h\"\n#include \"benchmark/state.h\"\n#include \"benchmark/ty"
},
{
"path": "test/benchmark_setup_teardown_test.cc",
"chars": 4197,
"preview": "#include <atomic>\n#include <cassert>\n#include <cstdlib>\n#include <cstring>\n#include <string>\n\n#include \"benchmark/benchm"
},
{
"path": "test/benchmark_test.cc",
"chars": 9147,
"preview": "#include <assert.h>\n#include <math.h>\n#include <stdint.h>\n\n#include <chrono>\n#include <complex>\n#include <cstdlib>\n#incl"
},
{
"path": "test/clobber_memory_assembly_test.cc",
"chars": 1423,
"preview": "#include \"benchmark/macros.h\"\n#include \"benchmark/utils.h\"\n\n#ifdef __clang__\n#pragma clang diagnostic ignored \"-Wreturn-"
},
{
"path": "test/commandlineflags_gtest.cc",
"chars": 6306,
"preview": "#include <cstdlib>\n\n#include \"../src/commandlineflags.h\"\n#include \"../src/internal_macros.h\"\n#include \"gmock/gmock.h\"\n#i"
},
{
"path": "test/complexity_test.cc",
"chars": 10877,
"preview": "#undef NDEBUG\n#include <cassert>\n#include <cmath>\n#include <cstdlib>\n#include <vector>\n\n#include \"benchmark/benchmark_ap"
},
{
"path": "test/cxx11_test.cc",
"chars": 373,
"preview": "#include \"benchmark/benchmark_api.h\"\n\n#if defined(_MSC_VER)\n#if _MSVC_LANG != 201402L\n// MSVC, even in C++11 mode, dooes"
},
{
"path": "test/diagnostics_test.cc",
"chars": 2614,
"preview": "// Testing:\n// State::PauseTiming()\n// State::ResumeTiming()\n// Test that CHECK's within these function diagnose whe"
},
{
"path": "test/display_aggregates_only_test.cc",
"chars": 1919,
"preview": "\n#undef NDEBUG\n#include <cstdio>\n#include <string>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registratio"
},
{
"path": "test/donotoptimize_assembly_test.cc",
"chars": 5375,
"preview": "#include \"benchmark/macros.h\"\n#include \"benchmark/utils.h\"\n\n#ifdef __clang__\n#pragma clang diagnostic ignored \"-Wreturn-"
},
{
"path": "test/donotoptimize_test.cc",
"chars": 1611,
"preview": "#include <cstdint>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/utils.h\"\n\nnamespace {\n#if defined(__GNUC__)"
},
{
"path": "test/filter_test.cc",
"chars": 3049,
"preview": "#include <algorithm>\n#include <cassert>\n#include <cmath>\n#include <cstdint>\n#include <cstdlib>\n#include <iostream>\n#incl"
},
{
"path": "test/fixture_test.cc",
"chars": 1283,
"preview": "\n#include <cassert>\n#include <memory>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registration.h\"\n#include"
},
{
"path": "test/internal_threading_test.cc",
"chars": 5811,
"preview": "\n#undef NDEBUG\n\n#include <chrono>\n#include <thread>\n\n#include \"../src/timers.h\"\n#include \"benchmark/benchmark_api.h\"\n#in"
},
{
"path": "test/link_main_test.cc",
"chars": 389,
"preview": "#include \"benchmark/registration.h\"\n#include \"benchmark/state.h\"\n#include \"benchmark/utils.h\"\n\nnamespace {\nvoid BM_empty"
},
{
"path": "test/locale_impermeability_test.cc",
"chars": 1731,
"preview": "#undef NDEBUG\n#include <cassert>\n#include <cmath>\n#include <cstdlib>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"ben"
},
{
"path": "test/manual_threading_test.cc",
"chars": 5017,
"preview": "\n#include <memory>\n#undef NDEBUG\n\n#include <chrono>\n#include <thread>\n\n#include \"../src/timers.h\"\n#include \"benchmark/be"
},
{
"path": "test/map_test.cc",
"chars": 1591,
"preview": "#include <cstdlib>\n#include <map>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registration.h\"\n#include \"be"
},
{
"path": "test/memory_manager_test.cc",
"chars": 2005,
"preview": "#include <memory>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/managers.h\"\n#include \"benchmark/registration"
},
{
"path": "test/memory_results_gtest.cc",
"chars": 2705,
"preview": "#include <vector>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/managers.h\"\n#include \"benchmark/reporter.h\"\n"
},
{
"path": "test/min_time_parse_gtest.cc",
"chars": 951,
"preview": "#include \"../src/benchmark_runner.h\"\n#include \"gtest/gtest.h\"\n\nnamespace {\n\nTEST(ParseMinTimeTest, InvalidInput) {\n#if G"
},
{
"path": "test/multiple_ranges_test.cc",
"chars": 2864,
"preview": "#include <cassert>\n#include <iostream>\n#include <set>\n#include <vector>\n\n#include \"benchmark/benchmark_api.h\"\n#include \""
},
{
"path": "test/options_test.cc",
"chars": 2456,
"preview": "#include <chrono>\n#include <thread>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registration.h\"\n#include \""
},
{
"path": "test/output_test.h",
"chars": 8025,
"preview": "#ifndef TEST_OUTPUT_TEST_H\n#define TEST_OUTPUT_TEST_H\n\n#undef NDEBUG\n#include <functional>\n#include <initializer_list>\n#"
},
{
"path": "test/output_test_helper.cc",
"chars": 18325,
"preview": "#include <cstdio>\n#include <cstring>\n#include <fstream>\n#include <iostream>\n#include <map>\n#include <memory>\n#include <r"
},
{
"path": "test/overload_test.cc",
"chars": 1109,
"preview": "#include \"benchmark/macros.h\"\n#include \"benchmark/registration.h\"\n#include \"benchmark/state.h\"\n\nnamespace {\n// Simulate "
},
{
"path": "test/perf_counters_gtest.cc",
"chars": 13510,
"preview": "#include <random>\n#include <thread>\n\n#include \"../src/perf_counters.h\"\n#include \"gmock/gmock.h\"\n#include \"gtest/gtest.h\""
},
{
"path": "test/perf_counters_test.cc",
"chars": 2561,
"preview": "#include <cstdarg>\n#undef NDEBUG\n\n#include \"../src/commandlineflags.h\"\n#include \"../src/perf_counters.h\"\n#include \"bench"
},
{
"path": "test/profiler_manager_gtest.cc",
"chars": 1100,
"preview": "#include <memory>\n\n#include \"benchmark/managers.h\"\n#include \"benchmark/registration.h\"\n#include \"benchmark/state.h\"\n#inc"
},
{
"path": "test/profiler_manager_iterations_test.cc",
"chars": 1935,
"preview": "#include <cassert>\n#include <cstdlib>\n#include <memory>\n#include <vector>\n\n#include \"benchmark/benchmark_api.h\"\n#include"
},
{
"path": "test/profiler_manager_test.cc",
"chars": 1927,
"preview": "// FIXME: WIP\n\n#include <cassert>\n#include <memory>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/managers.h"
},
{
"path": "test/register_benchmark_test.cc",
"chars": 6628,
"preview": "\n#undef NDEBUG\n#include <cassert>\n#include <vector>\n\n#include \"../src/check.h\" // NOTE: check.h is for internal use onl"
},
{
"path": "test/repetitions_test.cc",
"chars": 11733,
"preview": "\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registration.h\"\n#include \"benchmark/state.h\"\n#include \"output_"
},
{
"path": "test/report_aggregates_only_test.cc",
"chars": 1657,
"preview": "\n#undef NDEBUG\n#include <cstdio>\n#include <string>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registratio"
},
{
"path": "test/reporter_output_test.cc",
"chars": 57645,
"preview": "#undef NDEBUG\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registration.h\"\n#include \"benchmark/state.h\"\n#in"
},
{
"path": "test/skip_with_error_test.cc",
"chars": 7306,
"preview": "\n#undef NDEBUG\n#include <cassert>\n#include <vector>\n\n#include \"../src/check.h\" // NOTE: check.h is for internal use onl"
},
{
"path": "test/spec_arg_test.cc",
"chars": 3022,
"preview": "#include <algorithm>\n#include <cassert>\n#include <cstdint>\n#include <cstdlib>\n#include <cstring>\n#include <iostream>\n#in"
},
{
"path": "test/spec_arg_verbosity_test.cc",
"chars": 1204,
"preview": "#include <string.h>\n\n#include <iostream>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registration.h\"\n#incl"
},
{
"path": "test/state_assembly_test.cc",
"chars": 1874,
"preview": "#include \"benchmark/state.h\"\n#include \"benchmark/utils.h\"\n\n#ifdef __clang__\n#pragma clang diagnostic ignored \"-Wreturn-t"
},
{
"path": "test/statistics_gtest.cc",
"chars": 1361,
"preview": "//===---------------------------------------------------------------------===//\n// statistics_test - Unit tests for src/"
},
{
"path": "test/string_util_gtest.cc",
"chars": 5801,
"preview": "//===---------------------------------------------------------------------===//\n// string_util_test - Unit tests for src"
},
{
"path": "test/templated_fixture_method_test.cc",
"chars": 553,
"preview": "\n#include <cassert>\n#include <memory>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registration.h\"\n#include"
},
{
"path": "test/templated_fixture_test.cc",
"chars": 551,
"preview": "\n#include <cassert>\n#include <memory>\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registration.h\"\n#include"
},
{
"path": "test/time_unit_gtest.cc",
"chars": 915,
"preview": "#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/state.h\"\n#include \"gtest/gtest.h\"\n\nnamespace benchmark {\nnamesp"
},
{
"path": "test/user_counters_tabular_test.cc",
"chars": 29004,
"preview": "\n#undef NDEBUG\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/counter.h\"\n#include \"benchmark/registration.h\"\n"
},
{
"path": "test/user_counters_test.cc",
"chars": 27830,
"preview": "\n#undef NDEBUG\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/counter.h\"\n#include \"benchmark/registration.h\"\n"
},
{
"path": "test/user_counters_thousands_test.cc",
"chars": 9812,
"preview": "\n#undef NDEBUG\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/counter.h\"\n#include \"benchmark/registration.h\"\n"
},
{
"path": "test/user_counters_threads_test.cc",
"chars": 28620,
"preview": "\n#undef NDEBUG\n\n#include \"benchmark/benchmark_api.h\"\n#include \"benchmark/registration.h\"\n#include \"benchmark/state.h\"\n#i"
},
{
"path": "tools/BUILD.bazel",
"chars": 425,
"preview": "load(\"@rules_python//python:defs.bzl\", \"py_binary\", \"py_library\")\nload(\"@tools_pip_deps//:requirements.bzl\", \"requiremen"
},
{
"path": "tools/compare.py",
"chars": 19658,
"preview": "#!/usr/bin/env python3\n\n# type: ignore\n\n\"\"\"\ncompare.py - versatile benchmark output compare tool\n\"\"\"\n\nimport argparse\nim"
},
{
"path": "tools/gbench/Inputs/test1_run1.json",
"chars": 2689,
"preview": "{\n \"context\": {\n \"date\": \"2016-08-02 17:44:46\",\n \"num_cpus\": 4,\n \"mhz_per_cpu\": 4228,\n \"cpu_scaling_enabled"
},
{
"path": "tools/gbench/Inputs/test1_run2.json",
"chars": 2740,
"preview": "{\n \"context\": {\n \"date\": \"2016-08-02 17:44:46\",\n \"num_cpus\": 4,\n \"mhz_per_cpu\": 4228,\n \"cpu_scaling_enabled"
},
{
"path": "tools/gbench/Inputs/test2_run.json",
"chars": 1551,
"preview": "{\n \"context\": {\n \"date\": \"2016-08-02 17:44:46\",\n \"num_cpus\": 4,\n \"mhz_per_cpu\": 4228,\n \"cpu_scaling_enabled"
},
{
"path": "tools/gbench/Inputs/test3_run0.json",
"chars": 1266,
"preview": "{\n \"context\": {\n \"date\": \"2016-08-02 17:44:46\",\n \"num_cpus\": 4,\n \"mhz_per_cpu\": 4228,\n \"cpu_scaling_enabled"
},
{
"path": "tools/gbench/Inputs/test3_run1.json",
"chars": 1270,
"preview": "{\n \"context\": {\n \"date\": \"2016-08-02 17:44:46\",\n \"num_cpus\": 4,\n \"mhz_per_cpu\": 4228,\n \"cpu_scaling_enabled"
},
{
"path": "tools/gbench/Inputs/test4_run.json",
"chars": 2317,
"preview": "{\n \"benchmarks\": [\n {\n \"name\": \"99 family 0 instance 0 repetition 0\",\n \"run_type\": \"iteration\",\n \"fam"
},
{
"path": "tools/gbench/Inputs/test4_run0.json",
"chars": 431,
"preview": "{\n \"context\": {\n \"date\": \"2016-08-02 17:44:46\",\n \"num_cpus\": 4,\n \"mhz_per_cpu\": 4228,\n \"cpu_scaling_enabled"
},
{
"path": "tools/gbench/Inputs/test4_run1.json",
"chars": 432,
"preview": "{\n \"context\": {\n \"date\": \"2016-08-02 17:44:46\",\n \"num_cpus\": 4,\n \"mhz_per_cpu\": 4228,\n \"cpu_scaling_enabled"
},
{
"path": "tools/gbench/Inputs/test5_run0.json",
"chars": 404,
"preview": "{\n \"context\": {\n \"date\": \"2016-08-02 17:44:46\",\n \"num_cpus\": 4,\n \"mhz_per_cpu\": 4228,\n \"c"
},
{
"path": "tools/gbench/Inputs/test5_run1.json",
"chars": 404,
"preview": "{\n \"context\": {\n \"date\": \"2016-08-02 17:44:46\",\n \"num_cpus\": 4,\n \"mhz_per_cpu\": 4228,\n \"c"
},
{
"path": "tools/gbench/__init__.py",
"chars": 210,
"preview": "\"\"\"Google Benchmark tooling\"\"\"\n\n__author__ = \"Eric Fiselier\"\n__email__ = \"eric@efcs.ca\"\n__versioninfo__ = (0, 5, 0)\n__ve"
},
{
"path": "tools/gbench/report.py",
"chars": 56033,
"preview": "# type: ignore\n\n\"\"\"\nreport.py - Utilities for reporting statistics about benchmark results\n\"\"\"\n\nimport copy\nimport os\nim"
},
{
"path": "tools/gbench/util.py",
"chars": 7153,
"preview": "\"\"\"util.py - General utilities for running, loading, and processing\nbenchmarks\n\"\"\"\n\nimport json\nimport os\nimport re\nimpo"
},
{
"path": "tools/libpfm.BUILD.bazel",
"chars": 6972,
"preview": "\"\"\"Build rule for libpfm, which is required to collect performance counters for BENCHMARK_ENABLE_LIBPFM builds.\"\"\"\n\nload"
},
{
"path": "tools/requirements.txt",
"chars": 31,
"preview": "numpy == 2.4.3\nscipy == 1.17.1\n"
}
]
// ... and 3 more files (download for full content)
About this extraction
This page contains the full source code of the google/benchmark GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 203 files (983.8 KB), approximately 264.9k tokens, and a symbol index with 893 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.