blob: 9ffe6750c96939ed23e7e01976fb6a2c31f03749 [file] [edit]
//===- ImmutableSetBuildBM.cpp - Benchmark ImmutableSet construction ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Benchmarks the mutating operations of ImmutableSet -- add and remove -- which
// exercise the ImutAVLFactory node bookkeeping (createNode / recoverNodes) that
// the iterator benchmark deliberately keeps out of its timed region. Run the
// binary before and after a change and compare the two reports (e.g. with
// llvm/utils/compare.py).
//
// * Build - build an N-element set from empty (N add calls).
// * BuildRemove - build an N-element set, then remove every element.
//
//===----------------------------------------------------------------------===//
#include "benchmark/benchmark.h"
#include "llvm/ADT/ImmutableSet.h"
#include <algorithm>
#include <numeric>
#include <random>
#include <vector>
using namespace llvm;
namespace {
// Non-canonicalizing set (matches the dataflow analyses' usage).
using IntSet =
ImmutableSet<int, ImutContainerInfo<int>, /*Canonicalize=*/false>;
// A shuffled [0, N) key sequence, so the tree is built in random order.
static std::vector<int> shuffledKeys(size_t N) {
std::vector<int> Vals(N);
std::iota(Vals.begin(), Vals.end(), 0);
std::mt19937 Rng(0xC0FFEE);
std::shuffle(Vals.begin(), Vals.end(), Rng);
return Vals;
}
static void BM_Build(benchmark::State &State) {
const size_t N = State.range(0);
std::vector<int> Vals = shuffledKeys(N);
for (auto _ : State) {
IntSet::Factory F;
IntSet S = F.getEmptySet();
for (int V : Vals)
S = F.add(S, V);
benchmark::DoNotOptimize(S.getRootWithoutRetain());
}
State.SetItemsProcessed(State.iterations() * N);
}
static void BM_BuildRemove(benchmark::State &State) {
const size_t N = State.range(0);
std::vector<int> Vals = shuffledKeys(N);
for (auto _ : State) {
IntSet::Factory F;
IntSet S = F.getEmptySet();
for (int V : Vals)
S = F.add(S, V);
for (int V : Vals)
S = F.remove(S, V);
benchmark::DoNotOptimize(S.getRootWithoutRetain());
}
State.SetItemsProcessed(State.iterations() * N * 2);
}
} // namespace
#define BUILD_SIZES Arg(256)->Arg(4096)->Arg(65536)
BENCHMARK(BM_Build)->Name("Build")->BUILD_SIZES;
BENCHMARK(BM_BuildRemove)->Name("BuildRemove")->BUILD_SIZES;
BENCHMARK_MAIN();