You've already forked Zygisk-Assistant
mirror of
https://github.com/snake-4/Zygisk-Assistant.git
synced 2025-09-06 06:37:02 +00:00
Initial commit
This commit is contained in:
251
module/jni/libcxx/benchmarks/formatter_float.bench.cpp
Normal file
251
module/jni/libcxx/benchmarks/formatter_float.bench.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <format>
|
||||
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
#include <string>
|
||||
|
||||
#include "CartesianBenchmarks.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
// *** Localization ***
|
||||
enum class LocalizationE { False, True };
|
||||
struct AllLocalizations : EnumValuesAsTuple<AllLocalizations, LocalizationE, 2> {
|
||||
static constexpr const char* Names[] = {"LocFalse", "LocTrue"};
|
||||
};
|
||||
|
||||
template <LocalizationE E>
|
||||
struct Localization {};
|
||||
|
||||
template <>
|
||||
struct Localization<LocalizationE::False> {
|
||||
static constexpr const char* fmt = "";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Localization<LocalizationE::True> {
|
||||
static constexpr const char* fmt = "L";
|
||||
};
|
||||
|
||||
// *** Types ***
|
||||
enum class TypeE { Float, Double, LongDouble };
|
||||
// TODO FMT Set to 3 after to_chars has long double suport.
|
||||
struct AllTypes : EnumValuesAsTuple<AllTypes, TypeE, 2> {
|
||||
static constexpr const char* Names[] = {"Float", "Double", "LongDouble"};
|
||||
};
|
||||
|
||||
template <TypeE E>
|
||||
struct Type {};
|
||||
|
||||
template <>
|
||||
struct Type<TypeE::Float> {
|
||||
using type = float;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Type<TypeE::Double> {
|
||||
using type = double;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Type<TypeE::LongDouble> {
|
||||
using type = long double;
|
||||
};
|
||||
|
||||
// *** Values ***
|
||||
enum class ValueE { Inf, Random };
|
||||
struct AllValues : EnumValuesAsTuple<AllValues, ValueE, 2> {
|
||||
static constexpr const char* Names[] = {"Inf", "Random"};
|
||||
};
|
||||
|
||||
template <ValueE E>
|
||||
struct Value {};
|
||||
|
||||
template <>
|
||||
struct Value<ValueE::Inf> {
|
||||
template <class F>
|
||||
static std::array<F, 1000> make_data() {
|
||||
std::array<F, 1000> result;
|
||||
std::fill(result.begin(), result.end(), -std::numeric_limits<F>::infinity());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Value<ValueE::Random> {
|
||||
template <class F>
|
||||
static std::array<F, 1000> make_data() {
|
||||
std::random_device seed;
|
||||
std::mt19937 generator(seed());
|
||||
std::uniform_int_distribution<std::conditional_t<sizeof(F) == sizeof(uint32_t), uint32_t, uint64_t>> distribution;
|
||||
|
||||
std::array<F, 1000> result;
|
||||
std::generate(result.begin(), result.end(), [&] {
|
||||
while (true) {
|
||||
auto result = std::bit_cast<F>(distribution(generator));
|
||||
if (std::isfinite(result))
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// *** Display Type ***
|
||||
enum class DisplayTypeE {
|
||||
Default,
|
||||
Hex,
|
||||
Scientific,
|
||||
Fixed,
|
||||
General,
|
||||
};
|
||||
struct AllDisplayTypes : EnumValuesAsTuple<AllDisplayTypes, DisplayTypeE, 5> {
|
||||
static constexpr const char* Names[] = {"DisplayDefault", "DisplayHex", "DisplayScientific", "DisplayFixed",
|
||||
"DisplayGeneral"};
|
||||
};
|
||||
|
||||
template <DisplayTypeE E>
|
||||
struct DisplayType {};
|
||||
|
||||
template <>
|
||||
struct DisplayType<DisplayTypeE::Default> {
|
||||
static constexpr const char* fmt = "";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DisplayType<DisplayTypeE::Hex> {
|
||||
static constexpr const char* fmt = "a";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DisplayType<DisplayTypeE::Scientific> {
|
||||
static constexpr const char* fmt = "e";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DisplayType<DisplayTypeE::Fixed> {
|
||||
static constexpr const char* fmt = "f";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DisplayType<DisplayTypeE::General> {
|
||||
static constexpr const char* fmt = "g";
|
||||
};
|
||||
|
||||
// *** Alignment ***
|
||||
enum class AlignmentE { None, Left, Center, Right, ZeroPadding };
|
||||
struct AllAlignments : EnumValuesAsTuple<AllAlignments, AlignmentE, 5> {
|
||||
static constexpr const char* Names[] = {"AlignNone", "AlignmentLeft", "AlignmentCenter", "AlignmentRight",
|
||||
"ZeroPadding"};
|
||||
};
|
||||
|
||||
template <AlignmentE E>
|
||||
struct Alignment {};
|
||||
|
||||
template <>
|
||||
struct Alignment<AlignmentE::None> {
|
||||
static constexpr const char* fmt = "";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Alignment<AlignmentE::Left> {
|
||||
// Width > PrecisionE::Huge
|
||||
static constexpr const char* fmt = "0<17500";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Alignment<AlignmentE::Center> {
|
||||
// Width > PrecisionE::Huge
|
||||
static constexpr const char* fmt = "0^17500";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Alignment<AlignmentE::Right> {
|
||||
// Width > PrecisionE::Huge
|
||||
static constexpr const char* fmt = "0>17500";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Alignment<AlignmentE::ZeroPadding> {
|
||||
// Width > PrecisionE::Huge
|
||||
static constexpr const char* fmt = "017500";
|
||||
};
|
||||
|
||||
enum class PrecisionE { None, Zero, Small, Huge };
|
||||
struct AllPrecisions : EnumValuesAsTuple<AllPrecisions, PrecisionE, 4> {
|
||||
static constexpr const char* Names[] = {"PrecNone", "PrecZero", "PrecSmall", "PrecHuge"};
|
||||
};
|
||||
|
||||
template <PrecisionE E>
|
||||
struct Precision {};
|
||||
|
||||
template <>
|
||||
struct Precision<PrecisionE::None> {
|
||||
static constexpr const char* fmt = "";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Precision<PrecisionE::Zero> {
|
||||
static constexpr const char* fmt = ".0";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Precision<PrecisionE::Small> {
|
||||
static constexpr const char* fmt = ".10";
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Precision<PrecisionE::Huge> {
|
||||
// The maximum precision for a minimal sub normal long double is ±0x1p-16494.
|
||||
// This value is always larger than that value forcing the trailing zero path
|
||||
// to be executed.
|
||||
static constexpr const char* fmt = ".17000";
|
||||
};
|
||||
|
||||
template <class L, class DT, class T, class V, class A, class P>
|
||||
struct FloatingPoint {
|
||||
using F = typename Type<T::value>::type;
|
||||
|
||||
void run(benchmark::State& state) const {
|
||||
std::array<F, 1000> data{Value<V::value>::template make_data<F>()};
|
||||
std::array<char, 20'000> output;
|
||||
|
||||
while (state.KeepRunningBatch(1000))
|
||||
for (F value : data)
|
||||
benchmark::DoNotOptimize(std::format_to(output.begin(), std::string_view{fmt.data(), fmt.size()}, value));
|
||||
}
|
||||
|
||||
std::string name() const {
|
||||
return "FloatingPoint" + L::name() + DT::name() + T::name() + V::name() + A::name() + P::name();
|
||||
}
|
||||
|
||||
static constexpr std::string make_fmt() {
|
||||
return std::string("{:") + Alignment<A::value>::fmt + Precision<P::value>::fmt + Localization<L::value>::fmt +
|
||||
DisplayType<DT::value>::fmt + "}";
|
||||
}
|
||||
|
||||
static constexpr auto fmt = []() {
|
||||
constexpr size_t s = make_fmt().size();
|
||||
std::array<char, s> r;
|
||||
std::ranges::copy(make_fmt(), r.begin());
|
||||
return r;
|
||||
}();
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
benchmark::Initialize(&argc, argv);
|
||||
if (benchmark::ReportUnrecognizedArguments(argc, argv))
|
||||
return 1;
|
||||
|
||||
makeCartesianProductBenchmark<FloatingPoint, AllLocalizations, AllDisplayTypes, AllTypes, AllValues, AllAlignments,
|
||||
AllPrecisions>();
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
}
|
||||
Reference in New Issue
Block a user