How are people benchmarking their hot thread(s) or how to use google benchmark in JUCE?

Hi there,

Looking to see if others have gone down the rabbit hole of microbenchmarking in JUCE. Anyone have any luck getting Google Benchmark running ? Or are there other similar tools people are using ?

Just to clarify, looking for a microbenchmarking tool - am already happy with respect to macro benchmarking or profiling tools. Some thing I can wire up to my specific methods and their loops, or mock up similar to a unit test, that will then spit out some nice tables of mean times, variance etc. (apparently Google Benchmarking does this well).

With Google Benchmark, I’m a bit confused where to put the initialization code.

Thanks in advance for your help

I use it extensively for DSP.

In the projucer, create a “console application” project, and add the benchmark include/lib directory to the include/linker path and put “benchmark” in the “external libraries to link” field of the exporter. Then go into main.cpp and delete the main function, replacing it with BENCHMARK_MAIN();

Quick and dirty code:

#include "../JuceLibraryCode/JuceHeader.h"
#include "../whatever/you/want/to/bench.h"
#include <benchmark/benchmark.h> 


void MyBenchmark (benchmark::State& state) {
    for (auto _ : state) {
        auto result = something_to_benchmark(); 
        benchmark::DoNotOptimize(result); 
    }
}
BENCHMARK(MyBenchmark);
BENCHMARK_MAIN(); 

If you need more complicated setup for whatever you’re trying to benchmark you can use the benchmark::Fixture interface. Here’s an example, benchmarking a JUCE operation:

#include "../JuceLibraryCode/JuceHeader.h"
#include <benchmark/benchmark.h>
#include <string>
class Fixture : public benchmark::Fixture {
public:
    String message;
    void SetUp(const ::benchmark::State& state) {
        message = "setup";
    }

    void TearDown(const ::benchmark::State& state) {
        message = "teardown";
    }
};

BENCHMARK_F(Fixture, StringAppend)(benchmark::State& state) {
    for (auto _ : state) {
        message += "append";
    }
}

BENCHMARK_REGISTER_F(Fixture, StringAppend);
BENCHMARK_MAIN();
4 Likes

Many thanks for the detailed example.

Haven’t completely got everything set up since wasting time on figuring out a nasty linker error, caused by me forgetting to set a linker flag. For anyone in the same boat, Projucer should be set as such:

fwiw on MacOS you can brew install google-benchmark and it will be placed in /usr/local/lib with headers in /usr/local/include, then you just make sure they’re in your linker/include paths in your environment and it “just works.”

It helps when you just want to run some micro benches from the command line.

2 Likes