Simple, fast, accurate single-header microbenchmarking functionality for C++11/14/17/20

Overview

ankerl::nanobench

ankerl::nanobench logo

Release GitHub license Travis CI Build Status Appveyor Build Status Join the chat at https://gitter.im/nanobench/community

ankerl::nanobench is a platform independent microbenchmarking library for C++11/14/17/20.

5.0) { d -= 5.0; } ankerl::nanobench::doNotOptimizeAway(d); }); } ">
#define ANKERL_NANOBENCH_IMPLEMENT
#include <nanobench.h>

int main() {
    double d = 1.0;
    ankerl::nanobench::Bench().run("some double ops", [&] {
        d += 1.0 / d;
        if (d > 5.0) {
            d -= 5.0;
        }
        ankerl::nanobench::doNotOptimizeAway(d);
    });
}

The whole executable runs for ~60ms and prints

|               ns/op |                op/s |    err% |          ins/op |          cyc/op |    IPC |         bra/op |   miss% |     total | benchmark
|--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
|                7.52 |      132,948,239.79 |    1.1% |            6.65 |           24.07 |  0.276 |           1.00 |    8.9% |      0.00 | `some double ops`

Which github renders as

ns/op op/s err% ins/op cyc/op IPC bra/op miss% total benchmark
7.52 132,948,239.79 1.1% 6.65 24.07 0.276 1.00 8.9% 0.00 some double ops

The benchmarked code takes 7.52 nanoseconds to run, so ~133 million times per seconds. Measurements fluctuate by 1.1%. On average 6.65 instructions are executed in 24.07 CPU cycles, resulting in 0.276 instructions per cycle. A single branch is in the code, which branch prediction missed in 8.9% of the cases. Total runtime of the benchmark with the name some double ops is 0.00, so just a few milliseconds.

Design Goals

Documentation

Extensive documentation is available.

More

  • Code of Conduct - Contributor Covenant Code of Conduct
  • I need a better logo. Currently I use a small bench. Nanobench. Ha ha.
Comments
  • Idea? Timing only particular sections of code

    Idea? Timing only particular sections of code

    Recently I've been testing a few different sorting algorithms, the rough setup has a preallocated block of memory filled with random data. However that means for each benchmark run after a sort, I have to scramble or generate more random data, and this code is shared between all the benchmarks. Which roughly translates to a benchmark which is really measuring the cost of those two things together, rather than just the sorting algorithm on its own. Presumably the sort algorithm overwhelms the cost of generating new data, but it's difficult to gauge exactly how much of a cost generating data is without running a benchmark with that part on it's own.

    It seems almost as if with a few edits to add additional callbacks it'd be possible to add timings or even ignore parts of code which are not really part of the test. If a second callback doesn't make the code more unstable / slow to test it'd probably be a handy tool for cases like this.

    Might look like:

        template <typename Start, typename Op, typename End>
        ANKERL_NANOBENCH(NOINLINE)
        Bench& run(std::string const& benchmarkName, Start&& start, Op&& op, End&& end);
    
    opened by Andersama 6
  • Use steady_clock instead of high_resolution_clock

    Use steady_clock instead of high_resolution_clock

    std::high_resolution_clock is nothing but an alias to either system or steady clock, which means it can differ from one std library implementation to another. libstdc++ for example will use the realtime clock which is less precise than the monotone clock (steady). An interesting resource about clocks speed and precision is available at https://gitlab.com/chriscox/CppPerformanceBenchmarks/-/wikis/ClockTimeAnalysis . Howard Hinnant (who wrote the scpecification) also says it was a mistake to even standardize it (https://youtu.be/adSAN282YIw?t=4612). Google benchmark uses high_resolution_clock only if high_resolution_clock::is_steady() returns true, otherwise uses steady_clock.

    Ideally it might be interesting to provide our own clock using clock_gettime, QueryPerformanceCounter directly. An alternative would be to use rdtsc directly but there are issues with it on some CPUs, and it is x86 only.

    opened by Lectem 5
  • Doesn't compile on macOS

    Doesn't compile on macOS

    Works great for me on Linux but not on macOS:

      FAILED: _deps/nanobench-build/CMakeFiles/nanobench.dir/src/test/app/nanobench.cpp.o 
      ccache /usr/local/opt/ccache/libexec/c++  -I_deps/nanobench-src/src/include -isysroot /Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk -mmacosx-version-min=10.14 -MD -MT _deps/nanobench-build/CMakeFiles/nanobench.dir/src/test/app/nanobench.cpp.o -MF _deps/nanobench-build/CMakeFiles/nanobench.dir/src/test/app/nanobench.cpp.o.d -o _deps/nanobench-build/CMakeFiles/nanobench.dir/src/test/app/nanobench.cpp.o -c _deps/nanobench-src/src/test/app/nanobench.cpp
      In file included from _deps/nanobench-src/src/test/app/nanobench.cpp:2:
      Warning: _deps/nanobench-src/src/include/nanobench.h:117:15: warning: alias declarations are a C++11 extension [-Wc++11-extensions]
      using Clock = std::conditional<std::chrono::high_resolution_clock::is_steady, std::chrono::high_resolution_clock,
                    ^
      Error: _deps/nanobench-src/src/include/nanobench.h:296:19: error: expected function body after function declarator
      char const* csv() noexcept;
                        ^
      Error: _deps/nanobench-src/src/include/nanobench.h:308:27: error: expected function body after function declarator
      char const* htmlBoxplot() noexcept;
                                ^
      Error: _deps/nanobench-src/src/include/nanobench.h:319:20: error: expected function body after function declarator
      char const* json() noexcept;
                         ^
      Error: _deps/nanobench-src/src/include/nanobench.h:347:7: error: function definition does not declare parameters
          T pageFaults{};
            ^
      Error: _deps/nanobench-src/src/include/nanobench.h:348:7: error: function definition does not declare parameters
          T cpuCycles{};
            ^
      Error: _deps/nanobench-src/src/include/nanobench.h:349:7: error: function definition does not declare parameters
          T contextSwitches{};
            ^
      Error: _deps/nanobench-src/src/include/nanobench.h:350:7: error: function definition does not declare parameters
          T instructions{};
            ^
      Error: _deps/nanobench-src/src/include/nanobench.h:351:7: error: function definition does not declare parameters
          T branchInstructions{};
            ^
      Error: _deps/nanobench-src/src/include/nanobench.h:352:7: error: function definition does not declare parameters
          T branchMisses{};
            ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:360:33: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          std::string mBenchmarkTitle = "benchmark";
                                      ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:361:32: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          std::string mBenchmarkName = "noname";
                                     ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:362:23: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          std::string mUnit = "op";
                            ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:363:19: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          double mBatch = 1.0;
                        ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:364:25: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          double mComplexityN = -1.0;
                              ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:365:23: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          size_t mNumEpochs = 11;
                            ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:366:37: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          size_t mClockResolutionMultiple = static_cast<size_t>(1000);
                                          ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:367:44: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          std::chrono::nanoseconds mMaxEpochTime = std::chrono::milliseconds(100);
                                                 ^
      Error: _deps/nanobench-src/src/include/nanobench.h:368:30: error: function definition does not declare parameters
          std::chrono::nanoseconds mMinEpochTime{};
                                   ^
      Error: _deps/nanobench-src/src/include/nanobench.h:369:14: error: function definition does not declare parameters
          uint64_t mMinEpochIterations{1};
                   ^
      Error: _deps/nanobench-src/src/include/nanobench.h:370:14: error: function definition does not declare parameters
          uint64_t mEpochIterations{0}; // If not 0, run *exactly* these number of iterations per epoch.
                   ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:371:22: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          uint64_t mWarmup = 0;
                           ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:372:24: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          std::ostream* mOut = nullptr;
                             ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:373:45: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          std::chrono::duration<double> mTimeUnit = std::chrono::nanoseconds{1};
                                                  ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:374:31: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          std::string mTimeUnitName = "ns";
                                    ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:375:35: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          bool mShowPerformanceCounters = true;
                                        ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:376:22: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions]
          bool mIsRelative = false;
                           ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:381:29: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
          Config& operator=(Config&&);
                                  ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:383:18: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
          Config(Config&&) noexcept;
                       ^
      Error: _deps/nanobench-src/src/include/nanobench.h:383:21: error: expected ';' at end of declaration list
          Config(Config&&) noexcept;
                          ^
                          ;
      Error: _deps/nanobench-src/src/include/nanobench.h:373:71: error: expected '(' for function-style cast or type construction
          std::chrono::duration<double> mTimeUnit = std::chrono::nanoseconds{1};
                                                    ~~~~~~~~~~~~~~~~~~~~~~~~^
      Warning: _deps/nanobench-src/src/include/nanobench.h:391:10: warning: scoped enumerations are a C++11 extension [-Wc++11-extensions]
          enum class Measure : size_t {
               ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:407:29: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
          Result& operator=(Result&&);
                                  ^
      Warning: _deps/nanobench-src/src/include/nanobench.h:409:18: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
          Result(Result&&) noexcept;
                       ^
      Error: _deps/nanobench-src/src/include/nanobench.h:409:21: error: expected ';' at end of declaration list
          Result(Result&&) noexcept;
                          ^
                          ;
      Error: _deps/nanobench-src/src/include/nanobench.h:415:61: error: expected ';' at end of declaration list
          ANKERL_NANOBENCH(NODISCARD) Config const& config() const noexcept;
                                                                  ^
                                                                  ;
      Error: _deps/nanobench-src/src/include/nanobench.h:420:60: error: expected ';' at end of declaration list
          ANKERL_NANOBENCH(NODISCARD) double sum(Measure m) const noexcept;
                                                                 ^
                                                                 ;
      Error: _deps/nanobench-src/src/include/nanobench.h:421:80: error: expected ';' at end of declaration list
          ANKERL_NANOBENCH(NODISCARD) double sumProduct(Measure m1, Measure m2) const noexcept;
                                                                                     ^
                                                                                     ;
      Error: _deps/nanobench-src/src/include/nanobench.h:422:64: error: expected ';' at end of declaration list
          ANKERL_NANOBENCH(NODISCARD) double minimum(Measure m) const noexcept;
                                                                     ^
                                                                     ;
      fatal error: too many errors emitted, stopping now [-ferror-limit=]
    
    opened by vadi2 4
  • the cycles/value output doesn't show on some platform

    the cycles/value output doesn't show on some platform

    Hi,

    I'm using nanobench in some of my projects, everything's good. Some question though. On one of my linux system using arch-linux, I got all the cycles/value, IPC, branch etc measures displayed. One of my coworker use Linux Mint ubuntu 18.04 and he got non of those.

    Is there a specific package to install so that the extra perf counter get picked up ?

    opened by jfalcou 4
  • API of latest release (v3.1.0) doesn't match tutorial / README

    API of latest release (v3.1.0) doesn't match tutorial / README

    The latest v3.1.0 release does not match any of the examples since changing Config to Bench. This is quite a big (currently) undocumented API break and potentially warrants a new release?

    documentation 
    opened by chohner 4
  • comparisons of results

    comparisons of results

    Ability to store and later compare results. Maybe multiple results, to create a graph with changes over time

    Some statistical analysis would be nice. Maybe output in a format that's understood by some good tool

    enhancement 
    opened by martinus 4
  • Won't compile due to undefined references errors

    Won't compile due to undefined references errors

    It compiles fine with g++, fails with clang++ with e.g

    nb.cpp:(.text+0x2f): undefined reference to `ankerl::nanobench::Config::Config()'
    nb.cpp:(.text+0xcf): undefined reference to `ankerl::nanobench::Config::~Config()'
    nb.cpp:(.text+0x11d): undefined reference to `ankerl::nanobench::Config::~Config()'
    /tmp/nb-dff5f7.o: In function `ankerl::nanobench::Result ankerl::nanobench::Config::run<main::$_0>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, main::$_0)':
    nb.cpp:(.text+0x197): undefined reference to `ankerl::nanobench::detail::IterationLogic::IterationLogic(ankerl::nanobench::Config const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
    nb.cpp:(.text+0x1af): undefined reference to `ankerl::nanobench::detail::IterationLogic::numIters() const'
    nb.cpp:(.text+0x26f): undefined reference to `ankerl::nanobench::detail::IterationLogic::add(std::chrono::duration<long, std::ratio<1l, 1000000000l> >)'
    nb.cpp:(.text+0x2a2): undefined reference to `ankerl::nanobench::detail::IterationLogic::result() const'
    nb.cpp:(.text+0x2de): undefined reference to `ankerl::nanobench::detail::IterationLogic::result() const'
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    ``
    
    This is likely because the definition of those methods can't be resolved by clang++ somehow.
    
    opened by markpapadakis 4
  • how to deal with unstable results?

    how to deal with unstable results?

    I'm benchmarking protobuf. There are always some warning on unstable result on first run, even after increasing the warmup and minimum iteration:

    TEST_CASE("varint encode benchmark"){
    
        nanobench::Bench b;
        b.title("varint encode")
            .warmup(100000)
            .relative(true);
        b.performanceCounters(true);
    
        uint8_t buf[10] = {};
    
        b.minEpochIterations(10000000).run("google uint32_t", [&]{
            nanobench::doNotOptimizeAway(
                google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(static_cast<uint32_t>(2961488830), buf));
        });
    
        b.minEpochIterations(10000000).run("google uint64_t", [&]{
            nanobench::doNotOptimizeAway(
                google::protobuf::io::CodedOutputStream::WriteVarint64ToArray(static_cast<uint64_t>(-41256202580718336), buf));
        });
    
    //     std::ofstream f{"varint encode benchmark.html"};
    //     b.render(nanobench::templates::htmlBoxplot(), f);
    
    } // TEST_CASE("varint encode benchmark")
    
    
    TEST_CASE("varint decode benchmark"){
    
        nanobench::Bench b;
        b.title("varint decode")
            .warmup(100000)
            .relative(true);
        b.performanceCounters(true);
    
        std::initializer_list<uint8_t> buf32 = {0xbe, 0xf7, 0x92, 0x84, 0x0b};
        std::initializer_list<uint8_t> buf64 = {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01};
    
        b.minEpochIterations(10000000).run("google uint32_t", [&]{
            uint32_t v;
            nanobench::doNotOptimizeAway(
                google::protobuf::io::CodedInputStream{buf32.begin(), (int)buf32.size()}.ReadVarint32(&v));
        });
    
        b.minEpochIterations(10000000).run("google uint64_t", [&]{
            uint64_t v;
            nanobench::doNotOptimizeAway(
                google::protobuf::io::CodedInputStream{buf64.begin(), (int)buf64.size()}.ReadVarint64(&v));
        });
    
    //     std::ofstream f{"varint decode benchmark.html"};
    //     b.render(nanobench::templates::htmlBoxplot(), f);
    
    } // TEST_CASE("varint decode benchmark")
    

    encode results for 3 runs:

    | relative | ns/op | op/s | err% | total | varint encode |---------:|--------------------:|--------------------:|--------:|----------:|:-------------- | 100.0% | 6.95 | 143,943,329.37 | 5.3% | 0.87 | :wavy_dash: google uint32_t (Unstable with ~11,003,388.7 iters. Increase minEpochIterations to e.g. 110033887) | 54.0% | 12.86 | 77,751,471.35 | 2.0% | 1.56 | google uint64_t

    | relative | ns/op | op/s | err% | total | varint encode |---------:|--------------------:|--------------------:|--------:|----------:|:-------------- | 100.0% | 7.26 | 137,743,666.50 | 4.8% | 0.88 | google uint32_t | 55.0% | 13.21 | 75,702,505.04 | 1.6% | 1.62 | google uint64_t

    | relative | ns/op | op/s | err% | total | varint encode |---------:|--------------------:|--------------------:|--------:|----------:|:-------------- | 100.0% | 7.22 | 138,464,875.81 | 2.9% | 0.86 | google uint32_t | 56.4% | 12.80 | 78,102,820.79 | 1.9% | 1.55 | google uint64_t

    decode results for 3 runs:

    | relative | ns/op | op/s | err% | total | varint decode |---------:|--------------------:|--------------------:|--------:|----------:|:-------------- | 100.0% | 26.93 | 37,132,748.98 | 1.9% | 3.26 | google uint32_t | 101.0% | 26.67 | 37,490,487.35 | 3.4% | 3.23 | google uint64_t

    | relative | ns/op | op/s | err% | total | varint decode |---------:|--------------------:|--------------------:|--------:|----------:|:-------------- | 100.0% | 26.64 | 37,543,305.23 | 1.4% | 3.23 | google uint32_t | 102.7% | 25.93 | 38,558,548.08 | 1.2% | 3.17 | google uint64_t

    | relative | ns/op | op/s | err% | total | varint decode |---------:|--------------------:|--------------------:|--------:|----------:|:-------------- | 100.0% | 27.45 | 36,434,999.13 | 0.8% | 3.31 | google uint32_t | 103.1% | 26.62 | 37,568,188.30 | 2.8% | 3.23 | google uint64_t

    compiled with vs2019 16.8 msvc /O2 runs on Win10, [email protected]

    opened by feverzsj 3
  • Option to suppress unstable warnings at run-time?

    Option to suppress unstable warnings at run-time?

    Though it is a good thing to show warnings for unstable results (:wavy_dash: ... (Unstable with ...), sometimes one wants to run benchmarks in an environment where the execution is potentially perturbed by other processes and so results are known to be unstable; for example, in continuous integration.

    So, it might be handy if an environment variable (NANOBENCH_NO_UNSTABLE_WARNING or something) could change the behaviour and suppress warnings for unstable results.

    Changing the behaviour by a command-line option could be an alternative way, but I think an environment variable is more suitable for CI, and I guess it is easier to implement.

    enhancement 
    opened by tueda 3
  • Why a fork on pyperf?

    Why a fork on pyperf?

    Hi, Is there a reason why does it recommend a fork of pyperf (https://github.com/vstinner/pyperf) instead of pyperf itself? (https://github.com/psf/pyperf)

    Thanks!

    opened by elichai 3
  • which one is more important, ns/op or total?

    which one is more important, ns/op or total?

    | ns/op | op/s | err% | ins/op | cyc/op | IPC | bra/op | miss% | total | benchmark |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:---------- | 7,266,190.00 | 137.62 | 3.3% | 4,721,603.00 | 15,556,024.00 | 0.304 | 1,302,758.00 | 13.0% | 0.18 | hopscotch_map | 35,033,938.00 | 28.54 | 0.9% | 4,961,470.00 | 76,638,408.00 | 0.065 | 1,097,837.00 | 23.8% | 0.44 | unordered_map | 6,696,755.00 | 149.33 | 1.7% | 8,040,577.00 | 14,634,752.00 | 0.549 | 767,069.00 | 17.1% | 0.12 | flat_hash_map | 7,676,762.00 | 130.26 | 2.3% | 7,126,320.00 | 16,794,536.00 | 0.424 | 774,163.00 | 17.6% | 0.09 | F14FastMap

    flat_hash_map: ns/op : 6,696,755.00, total : 0.12 F14FastMap: ns/op: 7,676,762.00, total: 0.09

    opened by feng-y 2
  • Add CMake options to disable building tests and examples

    Add CMake options to disable building tests and examples

    When building the library using

    cmake -B build/ -S .
    cmake --build build/
    

    examples and tests are also built. Is it possible to add CMake options for disabling that (see, e.g., google benchmark)? It's useful for packaging.

    opened by tocic 0
  • Randomly unstable results on Alder Lake, Win 11

    Randomly unstable results on Alder Lake, Win 11

    Can give hugely (about 100 times slower) differ results when run AVX2 code

    int main(int argc, char ** argv)
    {
    	alignas(32) float res[8];
    	float * mem = static_cast<float *>(operator new(256, std::align_val_t(32)));
    	float * mulmem = static_cast<float *>(operator new(256, std::align_val_t(32)));
    
    	Bench().run("simd", [&]()
    	{
    		__m256 simdvec_ = _mm256_loadu_ps(mem);
    		__m256 simdvecmul_ = _mm256_loadu_ps(mulmem);
    		simdvec_ = _mm256_mul_ps(simdvec_, simdvecmul_);
    		_mm256_storeu_ps(res, simdvec_);
    	});
    	return res[0];
    }
    

    Sometimes when i rebuild writes about 0.5 ns/op, and when i relaunch writes about 29 ns/op, i think it related to Windows 11 thread manager or/and because my processor is Alder Lake i5-12600k with E-cores.

    Google Benchmark seems give more consistent results about 0.23 ns

    opened by Ok23 6
  • Setup with vcpkg

    Setup with vcpkg

    Trying to add nanobench via vcpkg manifest yields bizarre results. vcpkg manifest dependency looks like so,

    ...
        "dependencies": [
            "xtensor-blas",
            "nanobench",
            {
                "name": "highfive",
                "default-features": false,
                "features": [ "xtensor" ]
            },
    ...
    

    It only seems to be happy if I don't add anything to CMake at all. If I try to find_package(nanobench) or link against nanobench it complains that it can't be found or that I have to add to CMake_Prefix_List etc

    Is not having anything setup against it in CMake standard practice for this or is there some wizardry going on?

    opened by james-mxr 0
  • Manual Timing

    Manual Timing

    Is there a mechanism (similar to google benchmark) to perform manual timing. I.e. not use the clock builtin to nanbench but provide our own iteration time to nanobench.

    opened by abduld 3
Releases(v4.3.7)
  • v4.3.7(Apr 18, 2022)

    Direct download: nanobench.h

    • Documentation updates
    • Raise minimum epoch time to 1ms

    What's Changed

    • Add option to install library via cmake by @fferflo in https://github.com/martinus/nanobench/pull/60
    • Simplify documentation around benchmark comparison by @vadi2 in https://github.com/martinus/nanobench/pull/63

    New Contributors

    • @fferflo made their first contribution in https://github.com/martinus/nanobench/pull/60
    • @vadi2 made their first contribution in https://github.com/martinus/nanobench/pull/63

    Full Changelog: https://github.com/martinus/nanobench/compare/v4.3.6...v4.3.7

    Source code(tar.gz)
    Source code(zip)
  • v4.3.6(Sep 17, 2021)

    Direct download: nanobench.h

    • linux: Check for kernel >= 3.14 to enable performance counters
    • added a few sanitizer suppressions
    • regenerated documentation with latest releases of sphinx etc.

    What's Changed

    • Update README.md by @Tridacnid in https://github.com/martinus/nanobench/pull/55

    New Contributors

    • @Tridacnid made their first contribution in https://github.com/martinus/nanobench/pull/55

    Full Changelog: https://github.com/martinus/nanobench/compare/v4.3.5...v4.3.6

    Source code(tar.gz)
    Source code(zip)
  • v4.3.5(Jun 10, 2021)

  • v4.3.4(Jun 1, 2021)

  • v4.3.3(May 27, 2021)

  • v4.3.2(May 27, 2021)

    Direct download: nanobench.h

    • Fixed a MSVC 2015 build problem found by @eremyg-lunarg in robin-hood-hash. Thanks!
    • updates license to 2021.
    • Fix #52, build should now work with very old linux headers
    • Also disable UBSAN (bitcoin needed to add a suppression in https://github.com/bitcoin/bitcoin/pull/21738)
    Source code(tar.gz)
    Source code(zip)
  • v4.3.1(Feb 22, 2021)

    Direct download: nanobench.h

    • Minor cmake improvements when integrationg as a third-party library: add alias nanobench::nanobench, default to C++17

    What's Changed

    • Fix build with Visual Studio 16.8.2 by @pr8x in https://github.com/martinus/nanobench/pull/48

    New Contributors

    • @pr8x made their first contribution in https://github.com/martinus/nanobench/pull/48

    Full Changelog: https://github.com/martinus/nanobench/compare/v4.3.0...v4.3.1

    Source code(tar.gz)
    Source code(zip)
  • v4.3.0(Sep 28, 2020)

  • v4.2.0(Aug 26, 2020)

    Direct download: nanobench.h

    • #18 Ability to store and later compare results added, through pyperf.
      • See https://nanobench.ankerl.com/tutorial.html#pyperf-python-pyperf-module-output
    • #21 Added lots of build targets to travis, similar to bitcoin's build.
    • Some minor API & documentation improvements

    As of now, there is no open issue!

    Source code(tar.gz)
    Source code(zip)
  • v4.1.0(Aug 15, 2020)

    Direct download: nanobench.h

    • #38 Updated link to new pyperf home
    • #41 Adds ability to configure console output time unit
    • #39: Add support for environment variable NANOBENCH_SUPPRESS_WARNINGS
    • #42: Nanobench is now usable with CMake's FetchContent (see documentation: https://nanobench.ankerl.com/tutorial.html#cmake-integration)
    Source code(tar.gz)
    Source code(zip)
  • v4.0.2(Aug 1, 2020)

    Direct download: nanobench.h

    • Changed doNotOptimizeAway to what google benchmark is doing. The old code did not work on some machines.
    • fix #37: display correct "total" value
    • minor Documentation updates
    Source code(tar.gz)
    Source code(zip)
  • v4.0.0(Jun 13, 2020)

    New major release! Direct download: nanobench.h

    • API has been revised to be simpler and more intuitive. This is unfortunately not downward compatible, but the changes should be easy to fix. Most importantly, use now ankerl::nanobench::Bench instead of ankerl::nanobench::Config.
    • Clock is now always the fastest available steady clock.
    • Lots, and lots of documentation updates! See https://nanobench.ankerl.com. The documentation is now generated with the examples in the code, thus it will stay up to date much easier.
    • Faster Rng
    • Faster compile time, thanks to analysis with ClangBuildAnalyzer
    • Improved mustache templates for JSON, CSV, and HTML templates
    • Lots new templating features, with ability to calculate stuff
    • Ability to specify exactly the number of iterations you want
    • Lots of small & larger bugfixes
    Source code(tar.gz)
    Source code(zip)
  • v3.1.0(Nov 20, 2019)

  • v3.0.0(Nov 11, 2019)

  • v3.0.0-alpha(Oct 28, 2019)

  • v2.0.0(Oct 19, 2019)

Owner
Martin Leitner-Ankerl
s/Martin Ankerl/Martin Leitner-Ankerl/
Martin Leitner-Ankerl
A modern, C++11-native, single-file header-only, tiny framework for unit-tests, TDD and BDD (includes C++98 variant)

lest – lest errors escape testing This tiny C++11 test framework is based on ideas and examples by Kevlin Henney [1,2] and on ideas found in the CATCH

Martin Moene 348 Sep 19, 2022
Upp11 - C++11 lightweight single header unit test framework

upp11 Lightweight C++11 single header unit test framework To use framework: Copy upp11.h in you project dir. Create unit test source files or modify e

Andrey Valyaev 8 Apr 4, 2019
The fastest feature-rich C++11/14/17/20 single-header testing framework

master branch dev branch doctest is a new C++ testing framework but is by far the fastest both in compile times (by orders of magnitude) and runtime c

null 4.2k Sep 29, 2022
Header-only C++11 library for property-based testing.

autocheck Header-only C++11 library for QuickCheck (and later, SmallCheck) testing. Please consult the wiki for documentation. Install conan remote ad

John Freeman 120 Sep 29, 2022
A modern, C++-native, header-only, test framework for unit-tests, TDD and BDD - using C++11, C++14, C++17 and later (or C++03 on the Catch1.x branch)

Catch2 v3 is being developed! You are on the devel branch, where the next major version, v3, of Catch2 is being developed. As it is a significant rewo

Catch Org 15.6k Sep 26, 2022
Header only C++14 mocking framework

Trompeloeil Get: trompe l'oeil noun (Concise Encyclopedia) Style of representation in which a painted object is intended to deceive the viewer into be

Björn Fahller 642 Sep 23, 2022
C++ Unit Testing Easier: A Header-only C++ unit testing framework

CUTE C++ Unit Testing Easier: A Header-only C++ unit testing framework usually available as part of the Cevelop C++ IDE (http://cevelop.com) Dependenc

Peter Sommerlad 35 Aug 31, 2022
A complete unit testing framework in a header

liblittletest A complete unit testing framework in a header liblittletest is an easy to use all-in-an-header testing framework; all you have to do in

Sebastiano Merlino 13 Nov 11, 2021
C unit tests with a small header-only library.

C unit tests Minimalistic unit tests in C. Uses the __attribute__((constructor)) which, as far as I know, is supported by GCC and clang. So this proba

Ruben van Nieuwpoort 60 Aug 28, 2022
C++ mocking made easy. A simple yet very expressive, headers only library for c++ mocking.

FakeIt GCC: MSC: FakeIt is a simple mocking framework for C++. It supports GCC, Clang and MS Visual C++. FakeIt is written in C++11 and can be used fo

Eran Pe'er 1k Sep 28, 2022
QuickCheck clone for C++ with the goal of being simple to use with as little boilerplate as possible.

RapidCheck RapidCheck is a C++ framework for property based testing inspired by QuickCheck and other similar frameworks. In property based testing, yo

null 841 Sep 30, 2022
Simple C testing framework

MrTest Simple C testing framework Usage Copy the mrtest.c and mrtest.h file into your project. In order to use the mrtest main: create a .c file that

Maarten Raasveldt 2 Jul 20, 2022
A simple, cross-platform, and continuously integrated C++14 project template

Project Name A simple, cross-platform, and continuously integrated C++14 project template. Making cross platform C++ projects is widely known to be a

Arnav Borborah 62 Jul 27, 2022
MMCTX (Memory Management ConTeXualizer), is a tiny (< 300 lines), single header C99 library that allows for easier memory management by implementing contexts that remember allocations for you and provide freeall()-like functionality.

MMCTX (Memory Management ConTeXualizer), is a tiny (< 300 lines), single header C99 library that allows for easier memory management by implementing contexts that remember allocations for you and provide freeall()-like functionality.

A.P. Jo. 4 Oct 2, 2021
Solve 20 simple math questions and see how accurate/fast you are!

Math-Quiz Solve 20 simple math questions and see how accurate/fast you are! Want to try? Clone this repository $ git clone https://github.com/Mini-War

Mini Ware 8 Sep 11, 2022
A simple header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).

args Note that this library is essentially in maintenance mode. I haven't had the time to work on it or give it the love that it deserves. I'm not add

Taylor C. Richberger 1k Sep 22, 2022
A simple header-only C++ argument parser library. Supposed to be flexible and powerful, and attempts to be compatible with the functionality of the Python standard argparse library (though not necessarily the API).

args Note that this library is essentially in maintenance mode. I haven't had the time to work on it or give it the love that it deserves. I'm not add

Taylor C. Richberger 896 Aug 31, 2021
Tundra is a code build system that tries to be accurate and fast for incremental builds

Tundra, a build system Tundra is a high-performance code build system designed to give the best possible incremental build times even for very large s

Andreas Fredriksson 387 Oct 3, 2022
Fast and Accurate Extrinsic Calibration for Multiple LiDARs and Cameras

Fast and Accurate Extrinsic Calibration for Multiple LiDARs and Cameras The pre-print version of our paper is available here. The pre-release code has

HKU-Mars-Lab 220 Oct 1, 2022
BLEND: A Fast, Memory-Efficient, and Accurate Mechanism to Find Fuzzy Seed Matches

BLEND is a mechanism that can efficiently find fuzzy seed matches between sequences to significantly improve the performance and accuracy while reducing the memory space usage of two important applications: 1) finding overlapping reads and 2) read mapping.

SAFARI Research Group at ETH Zurich and Carnegie Mellon University 13 Sep 27, 2022