Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/multi output #112

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/include/nanobench.h
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,7 @@ void doNotOptimizeAway(T const& val) {
# include <fstream> // ifstream to parse proc files
# include <iomanip> // setw, setprecision
# include <iostream> // cout
# include <mutex> // mutex, lock_guard
# include <numeric> // accumulate
# include <random> // random_device
# include <sstream> // to_s in Number
Expand Down Expand Up @@ -1791,7 +1792,7 @@ void gatherStabilityInformation(std::vector<std::string>& warnings, std::vector<
void printStabilityInformationOnce(std::ostream* outStream);

// remembers the last table settings used. When it changes, a new table header is automatically written for the new entry.
uint64_t& singletonHeaderHash() noexcept;
uint64_t& singletonHeaderHash(std::ostream const& _out) noexcept;

// determines resolution of the given clock. This is done by measuring multiple times and returning the minimum time difference.
Clock::duration calcClockResolution(size_t numEvaluations) noexcept;
Expand Down Expand Up @@ -2104,9 +2105,12 @@ void printStabilityInformationOnce(std::ostream* outStream) {
}

// remembers the last table settings used. When it changes, a new table header is automatically written for the new entry.
uint64_t& singletonHeaderHash() noexcept {
static uint64_t sHeaderHash{};
return sHeaderHash;
uint64_t& singletonHeaderHash(std::ostream const& _out) noexcept {
static std::mutex sMutex;
static std::unordered_map<std::ostream const*, uint64_t> sHeaderHashes;
std::lock_guard<std::mutex> guard{sMutex};

return sHeaderHashes[&_out];
}

ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined")
Expand Down Expand Up @@ -2332,8 +2336,8 @@ struct IterationLogic::Impl {
hash = hash_combine(std::hash<bool>{}(mBench.relative()), hash);
hash = hash_combine(std::hash<bool>{}(mBench.performanceCounters()), hash);

if (hash != singletonHeaderHash()) {
singletonHeaderHash() = hash;
if (hash != singletonHeaderHash(os)) {
singletonHeaderHash(os) = hash;

// no result yet, print header
os << std::endl;
Expand Down
3 changes: 2 additions & 1 deletion src/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ target_sources_local(nb PRIVATE
tutorial_fluctuating_v1.cpp
tutorial_fluctuating_v2.cpp
tutorial_mustache.cpp
tutorial_render_simple.cpp
tutorial_render_simple.cpp
tutorial_slow_v1.cpp
tutorial_slow_v2.cpp
unit_api.cpp
unit_cold.cpp
unit_exact_iters_and_epochs.cpp
unit_multi_bench.cpp
unit_romutrio.cpp
unit_templates.cpp
unit_timeunit.cpp
Expand Down
67 changes: 67 additions & 0 deletions src/test/unit_multi_bench.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include <nanobench.h>
#include <thirdparty/doctest/doctest.h>

#include <iostream>
#include <map>
#include <sstream>
#include <unordered_map>



template <typename Container>
static void runTest(std::string container_name, ankerl::nanobench::Bench& bench_at, ankerl::nanobench::Bench& bench_operator) {
size_t const maxSize = 1000000;

ankerl::nanobench::Rng rng;

Container container;
for (size_t i{0}; i < maxSize; ++i) {
auto value = uint8_t(rng.bounded(256));
container[i] = value;
}
bench_at.run(container_name, [&] {
ankerl::nanobench::doNotOptimizeAway(container.at(rng.bounded(maxSize)));
});
bench_operator.run(container_name, [&] {
ankerl::nanobench::doNotOptimizeAway(container[rng.bounded(maxSize)]);
});
}

// NOLINTNEXTLINE
TEST_CASE("multi_bench") {
// Suppress any stability warnings for later outputs
ankerl::nanobench::Bench().run("suppress_warning", []{});

ankerl::nanobench::Bench bench_at;
std::stringstream output_at;
bench_at
.title("at()")
.output(&output_at);

ankerl::nanobench::Bench bench_operator;
std::stringstream output_operator;
bench_operator
.title("operator[]")
.output(&output_operator);


runTest<std::map<size_t, uint8_t> >("std::map", bench_at, bench_operator);
runTest<std::unordered_map<size_t, uint8_t> >("std::unordered_map", bench_at, bench_operator);

size_t linect_at{};
size_t linect_operator{};
{
std::string s;
while(std::getline(output_at, s)) {
linect_at += 1;
}
while(std::getline(output_operator, s)) {
linect_operator += 1;
}
}
CHECK(linect_at == 5);
CHECK(linect_operator == 5);

std::cout << output_at.str() << '\n'
<< output_operator.str() << '\n';
}