Created
June 14, 2025 23:43
-
-
Save vittorioromeo/af005862d97916d38428cf3464ef4703 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <benchmark/benchmark.h> | |
#include <cstdint> | |
enum class EDS_ScreenHuggingIconCorner : uint8_t | |
{ | |
TopLeft, | |
TopRight, | |
BottomLeft, | |
BottomRight, | |
None | |
}; | |
static EDS_ScreenHuggingIconCorner GetCornerBranchy(bool IsLeft, bool IsRight, bool IsTop, bool IsBottom) | |
{ | |
if (IsTop && IsLeft) | |
return EDS_ScreenHuggingIconCorner::TopLeft; | |
if (IsTop && IsRight) | |
return EDS_ScreenHuggingIconCorner::TopRight; | |
if (IsBottom && IsLeft) | |
return EDS_ScreenHuggingIconCorner::BottomLeft; | |
if (IsBottom && IsRight) | |
return EDS_ScreenHuggingIconCorner::BottomRight; | |
return EDS_ScreenHuggingIconCorner::None; | |
} | |
static EDS_ScreenHuggingIconCorner GetCornerBitmask(bool IsLeft, bool IsRight, bool IsTop, bool IsBottom) | |
{ | |
enum : uint8_t | |
{ | |
LeftBit = 0b0001, | |
RightBit = 0b0010, | |
TopBit = 0b0100, | |
BottomBit = 0b1000 | |
}; | |
switch ((IsLeft * LeftBit) | (IsRight * RightBit) | (IsTop * TopBit) | (IsBottom * BottomBit)) | |
{ | |
case (TopBit | LeftBit): | |
return EDS_ScreenHuggingIconCorner::TopLeft; | |
case (TopBit | RightBit): | |
return EDS_ScreenHuggingIconCorner::TopRight; | |
case (BottomBit | LeftBit): | |
return EDS_ScreenHuggingIconCorner::BottomLeft; | |
case (BottomBit | RightBit): | |
return EDS_ScreenHuggingIconCorner::BottomRight; | |
default: | |
return EDS_ScreenHuggingIconCorner::None; | |
} | |
} | |
static EDS_ScreenHuggingIconCorner GetCornerJumpTable(bool IsLeft, bool IsRight, bool IsTop, bool IsBottom) | |
{ | |
using enum EDS_ScreenHuggingIconCorner; | |
static constexpr EDS_ScreenHuggingIconCorner s_cornerTable[16] = { | |
None, // [0000] B=0, T=0, R=0, L=0 | |
None, // [0001] B=0, T=0, R=0, L=1 | |
None, // [0010] B=0, T=0, R=1, L=0 | |
None, // [0011] B=0, T=0, R=1, L=1 | |
None, // [0100] B=0, T=1, R=0, L=0 | |
TopLeft, // [0101] B=0, T=1, R=0, L=1 (Top | Left) | |
TopRight, // [0110] B=0, T=1, R=1, L=0 (Top | Right) | |
None, // [0111] B=0, T=1, R=1, L=1 | |
None, // [1000] B=1, T=0, R=0, L=0 | |
BottomLeft, // [1001] B=1, T=0, R=0, L=1 (Bottom | Left) | |
BottomRight, // [1010] B=1, T=0, R=1, L=0 (Bottom | Right) | |
None, // [1011] B=1, T=0, R=1, L=1 | |
None, // [1100] B=1, T=1, R=0, L=0 | |
None, // [1101] B=1, T=1, R=0, L=1 | |
None, // [1110] B=1, T=1, R=1, L=0 | |
None, // [1111] B=1, T=1, R=1, L=1 | |
}; | |
return s_cornerTable[(IsLeft << 0u) | (IsRight << 1u) | (IsTop << 2u) | (IsBottom << 3)]; | |
} | |
#include <random> | |
#include <vector> | |
struct BenchmarkInput | |
{ | |
bool IsLeft; | |
bool IsRight; | |
bool IsTop; | |
bool IsBottom; | |
}; | |
static std::vector<BenchmarkInput> GenerateRandomInputs(size_t count) | |
{ | |
std::vector<BenchmarkInput> inputs; | |
inputs.reserve(count); | |
std::mt19937 gen(std::random_device{}()); | |
std::uniform_int_distribution<> distrib(0, 1); | |
for (size_t i = 0; i < count; ++i) | |
inputs.emplace_back(static_cast<bool>(distrib(gen)), | |
static_cast<bool>(distrib(gen)), | |
static_cast<bool>(distrib(gen)), | |
static_cast<bool>(distrib(gen))); | |
return inputs; | |
} | |
static const std::vector<BenchmarkInput> s_randomInputs = GenerateRandomInputs(16'384); | |
static void GetCornerBranchy_Predictable_Benchmark(benchmark::State& state) | |
{ | |
size_t i = 0; | |
for (auto _ : state) | |
{ | |
auto result = GetCornerBranchy(i % 2, i % 3, i % 5, i % 7); | |
benchmark::DoNotOptimize(result); | |
++i; | |
} | |
} | |
BENCHMARK(GetCornerBranchy_Predictable_Benchmark); | |
static void GetCornerBitmask_Predictable_Benchmark(benchmark::State& state) | |
{ | |
size_t i = 0; | |
for (auto _ : state) | |
{ | |
auto result = GetCornerBitmask(i % 2, i % 3, i % 5, i % 7); | |
benchmark::DoNotOptimize(result); | |
++i; | |
} | |
} | |
BENCHMARK(GetCornerBitmask_Predictable_Benchmark); | |
static void GetCornerJumpTable_Predictable_Benchmark(benchmark::State& state) | |
{ | |
size_t i = 0; | |
for (auto _ : state) | |
{ | |
auto result = GetCornerJumpTable(i % 2, i % 3, i % 5, i % 7); | |
benchmark::DoNotOptimize(result); | |
++i; | |
} | |
} | |
BENCHMARK(GetCornerJumpTable_Predictable_Benchmark); | |
static void GetCornerBranchy_Unpredictable_Benchmark(benchmark::State& state) | |
{ | |
size_t i = 0; | |
for (auto _ : state) | |
{ | |
const auto& input = s_randomInputs[i % s_randomInputs.size()]; | |
auto result = GetCornerBranchy(input.IsLeft, input.IsRight, input.IsTop, input.IsBottom); | |
benchmark::DoNotOptimize(result); | |
++i; | |
} | |
} | |
BENCHMARK(GetCornerBranchy_Unpredictable_Benchmark); | |
static void GetCornerBitmask_Unpredictable_Benchmark(benchmark::State& state) | |
{ | |
size_t i = 0; | |
for (auto _ : state) | |
{ | |
const auto& input = s_randomInputs[i % s_randomInputs.size()]; | |
auto result = GetCornerBitmask(input.IsLeft, input.IsRight, input.IsTop, input.IsBottom); | |
benchmark::DoNotOptimize(result); | |
++i; | |
} | |
} | |
BENCHMARK(GetCornerBitmask_Unpredictable_Benchmark); | |
static void GetCornerJumpTable_Unpredictable_Benchmark(benchmark::State& state) | |
{ | |
size_t i = 0; | |
for (auto _ : state) | |
{ | |
const auto& input = s_randomInputs[i % s_randomInputs.size()]; | |
auto result = GetCornerJumpTable(input.IsLeft, input.IsRight, input.IsTop, input.IsBottom); | |
benchmark::DoNotOptimize(result); | |
++i; | |
} | |
} | |
BENCHMARK(GetCornerJumpTable_Unpredictable_Benchmark); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment