Browse Source

update: Benchmark module

master
Dnomd343 1 year ago
parent
commit
2c7ff2425d
  1. 102
      src/klotski_core/benchmark/benchmark.cc
  2. 104
      src/klotski_core/benchmark/benchmark.h
  3. 68
      src/klotski_core/benchmark/chore.cc

102
src/klotski_core/benchmark/benchmark.cc

@ -40,36 +40,36 @@ double Benchmark::all_cases(TIME format) noexcept {
/// -------------------------- Benchmark Code Check --------------------------- /// -------------------------- Benchmark Code Check ---------------------------
double Benchmark::raw_code_check(TIME format) noexcept { double Benchmark::raw_code_check(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&raw_code : all_raw_codes) { for (auto &&raw_code : all_raw_codes_) {
raw_code.valid(); raw_code.valid();
} }
return time_format(start, format) / (double)all_raw_codes.size(); return time_format(start, format) / (double)all_raw_codes_.size();
} }
double Benchmark::short_code_check(TIME format) noexcept { double Benchmark::short_code_check(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&short_code : all_short_codes) { for (auto &&short_code : all_short_codes_) {
short_code.valid(); short_code.valid();
} }
return time_format(start, format) / (double)all_short_codes.size(); return time_format(start, format) / (double)all_short_codes_.size();
} }
double Benchmark::common_code_check(TIME format) noexcept { double Benchmark::common_code_check(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&common_code : all_common_codes) { for (auto &&common_code : all_common_codes_) {
common_code.valid(); common_code.valid();
} }
return time_format(start, format) / (double)all_common_codes.size(); return time_format(start, format) / (double)all_common_codes_.size();
} }
double Benchmark::raw_code_check_random(TIME format) noexcept { double Benchmark::raw_code_check_random(TIME format) noexcept {
@ -108,167 +108,167 @@ double Benchmark::common_code_check_random(TIME format) noexcept {
/// -------------------------- Benchmark Code String -------------------------- /// -------------------------- Benchmark Code String --------------------------
double Benchmark::short_code_to_string(TIME format) noexcept { double Benchmark::short_code_to_string(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&short_code : all_short_codes) { for (auto &&short_code : all_short_codes_) {
short_code.to_string(); short_code.to_string();
} }
return time_format(start, format) / (double)all_short_codes.size(); return time_format(start, format) / (double)all_short_codes_.size();
} }
double Benchmark::short_code_from_string(TIME format) noexcept { double Benchmark::short_code_from_string(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&short_code : all_short_codes_str) { for (auto &&short_code : all_short_codes_str_) {
ShortCode{std::forward<std::string>(short_code)}; ShortCode{std::forward<std::string>(short_code)};
} }
return time_format(start, format) / (double)all_short_codes_str.size(); return time_format(start, format) / (double)all_short_codes_str_.size();
} }
double Benchmark::common_code_to_string(TIME format) noexcept { double Benchmark::common_code_to_string(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&common_code : all_common_codes) { for (auto &&common_code : all_common_codes_) {
common_code.to_string(); common_code.to_string();
} }
return time_format(start, format) / (double)all_common_codes.size(); return time_format(start, format) / (double)all_common_codes_.size();
} }
double Benchmark::common_code_from_string(TIME format) noexcept { double Benchmark::common_code_from_string(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&common_code : all_common_codes_str) { for (auto &&common_code : all_common_codes_str_) {
CommonCode{std::forward<std::string>(common_code)}; CommonCode{std::forward<std::string>(common_code)};
} }
return time_format(start, format) / (double)all_common_codes_str.size(); return time_format(start, format) / (double)all_common_codes_str_.size();
} }
/// ------------------------- Benchmark Code Convert -------------------------- /// ------------------------- Benchmark Code Convert --------------------------
double Benchmark::common_code_to_raw_code(TIME format) noexcept { double Benchmark::common_code_to_raw_code(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&common_code : all_common_codes) { for (auto &&common_code : all_common_codes_) {
RawCode{std::forward<CommonCode>(common_code)}; RawCode{std::forward<CommonCode>(common_code)};
} }
return time_format(start, format) / (double)all_common_codes.size(); return time_format(start, format) / (double)all_common_codes_.size();
} }
double Benchmark::raw_code_to_common_code(TIME format) noexcept { double Benchmark::raw_code_to_common_code(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&raw_code : all_raw_codes) { for (auto &&raw_code : all_raw_codes_) {
raw_code.to_common_code(); raw_code.to_common_code();
} }
return time_format(start, format) / (double)all_raw_codes.size(); return time_format(start, format) / (double)all_raw_codes_.size();
} }
double Benchmark::common_code_to_short_code(TIME format) noexcept { double Benchmark::common_code_to_short_code(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
uint32_t num = 0; uint32_t num = 0;
ShortCode::speed_up(ShortCode::NORMAL); ShortCode::speed_up(ShortCode::NORMAL);
auto start = clock(); auto start = clock();
for (uint64_t i = 0; i < all_common_codes.size(); i += 1000) { for (uint64_t i = 0; i < all_common_codes_.size(); i += 1000) {
ShortCode{all_common_codes[i]}; ShortCode{all_common_codes_[i]};
++num; ++num;
} }
return time_format(start, format) / (double)num; return time_format(start, format) / (double)num;
} }
double Benchmark::short_code_to_common_code(TIME format) noexcept { double Benchmark::short_code_to_common_code(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
uint32_t num = 0; uint32_t num = 0;
ShortCode::speed_up(ShortCode::NORMAL); ShortCode::speed_up(ShortCode::NORMAL);
auto start = clock(); auto start = clock();
for (uint64_t i = 0; i < all_short_codes.size(); i += 1000) { for (uint64_t i = 0; i < all_short_codes_.size(); i += 1000) {
all_short_codes[i].to_common_code(); all_short_codes_[i].to_common_code();
++num; ++num;
} }
return time_format(start, format) / (double)num; return time_format(start, format) / (double)num;
} }
double Benchmark::common_code_to_short_code_fast(TIME format) noexcept { double Benchmark::common_code_to_short_code_fast(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
ShortCode::speed_up(ShortCode::FAST); ShortCode::speed_up(ShortCode::FAST);
auto start = clock(); auto start = clock();
for (auto &&common_code : all_common_codes) { for (auto &&common_code : all_common_codes_) {
ShortCode{std::forward<CommonCode>(common_code)}; ShortCode{std::forward<CommonCode>(common_code)};
} }
return time_format(start, format) / (double)all_common_codes.size(); return time_format(start, format) / (double)all_common_codes_.size();
} }
double Benchmark::short_code_to_common_code_fast(TIME format) noexcept { double Benchmark::short_code_to_common_code_fast(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
ShortCode::speed_up(ShortCode::FAST); ShortCode::speed_up(ShortCode::FAST);
auto start = clock(); auto start = clock();
for (auto &&short_code : all_short_codes) { for (auto &&short_code : all_short_codes_) {
short_code.to_common_code(); short_code.to_common_code();
} }
return time_format(start, format) / (double)all_short_codes.size(); return time_format(start, format) / (double)all_short_codes_.size();
} }
/// ---------------------------- Benchmark Mirror ----------------------------- /// ---------------------------- Benchmark Mirror -----------------------------
double Benchmark::vertical_mirror_check(TIME format) noexcept { double Benchmark::vertical_mirror_check(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&raw_code : all_raw_codes) { for (auto &&raw_code : all_raw_codes_) {
raw_code.is_vertical_mirror(); raw_code.is_vertical_mirror();
} }
return time_format(start, format) / (double)all_raw_codes.size(); return time_format(start, format) / (double)all_raw_codes_.size();
} }
double Benchmark::horizontal_mirror_check(TIME format) noexcept { double Benchmark::horizontal_mirror_check(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&raw_code : all_raw_codes) { for (auto &&raw_code : all_raw_codes_) {
raw_code.is_horizontal_mirror(); raw_code.is_horizontal_mirror();
} }
return time_format(start, format) / (double)all_raw_codes.size(); return time_format(start, format) / (double)all_raw_codes_.size();
} }
double Benchmark::vertical_mirror_convert(TIME format) noexcept { double Benchmark::vertical_mirror_convert(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&raw_code : all_raw_codes) { for (auto &&raw_code : all_raw_codes_) {
raw_code.to_vertical_mirror(); raw_code.to_vertical_mirror();
} }
return time_format(start, format) / (double)all_raw_codes.size(); return time_format(start, format) / (double)all_raw_codes_.size();
} }
double Benchmark::horizontal_mirror_convert(TIME format) noexcept { double Benchmark::horizontal_mirror_convert(TIME format) noexcept {
if (!data_ready) { if (!data_ready_) {
return -1; // data no ready -> skip return -1; // data no ready -> skip
} }
auto start = clock(); auto start = clock();
for (auto &&raw_code : all_raw_codes) { for (auto &&raw_code : all_raw_codes_) {
raw_code.to_horizontal_mirror(); raw_code.to_horizontal_mirror();
} }
return time_format(start, format) / (double)all_raw_codes.size(); return time_format(start, format) / (double)all_raw_codes_.size();
} }

104
src/klotski_core/benchmark/benchmark.h

@ -27,55 +27,57 @@
#include "common_code.h" #include "common_code.h"
namespace klotski { namespace klotski {
class Benchmark {
public: class Benchmark {
enum TIME { public:
S, MS, US, NS enum TIME {
}; S, MS, US, NS
static void data_preparation() noexcept;
static double warm_up(uint64_t count) noexcept;
static double range_flip(TIME format = NS) noexcept;
static double all_cases(TIME format = MS) noexcept;
static double basic_ranges(TIME format = MS) noexcept;
static double raw_code_check(TIME format = NS) noexcept;
static double short_code_check(TIME format = NS) noexcept;
static double common_code_check(TIME format = NS) noexcept;
static double raw_code_check_random(TIME format = NS) noexcept;
static double short_code_check_random(TIME format = NS) noexcept;
static double common_code_check_random(TIME format = NS) noexcept;
static double short_code_to_string(TIME format = NS) noexcept;
static double short_code_from_string(TIME format = NS) noexcept;
static double common_code_to_string(TIME format = NS) noexcept;
static double common_code_from_string(TIME format = NS) noexcept;
static double common_code_to_raw_code(TIME format = NS) noexcept;
static double raw_code_to_common_code(TIME format = NS) noexcept;
static double common_code_to_short_code(TIME format = US) noexcept;
static double short_code_to_common_code(TIME format = US) noexcept;
static double common_code_to_short_code_fast(TIME format = NS) noexcept;
static double short_code_to_common_code_fast(TIME format = NS) noexcept;
static double vertical_mirror_check(TIME format = NS) noexcept;
static double horizontal_mirror_check(TIME format = NS) noexcept;
static double vertical_mirror_convert(TIME format = NS) noexcept;
static double horizontal_mirror_convert(TIME format = NS) noexcept;
private:
static bool data_ready;
static std::mutex data_building;
static std::vector<RawCode> all_raw_codes;
static std::vector<ShortCode> all_short_codes;
static std::vector<CommonCode> all_common_codes;
static std::vector<std::string> all_short_codes_str;
static std::vector<std::string> all_common_codes_str;
static void build_data() noexcept;
static uint32_t random_seed() noexcept;
static double time_format(clock_t start, TIME format) noexcept;
static std::vector<uint32_t> generate_u32_rand(uint32_t count) noexcept;
static std::vector<uint64_t> generate_u64_rand(uint32_t count) noexcept;
}; };
} static void data_initialize() noexcept;
static double warm_up(uint64_t count) noexcept;
static double range_flip(TIME format = NS) noexcept;
static double all_cases(TIME format = MS) noexcept;
static double basic_ranges(TIME format = MS) noexcept;
static double raw_code_check(TIME format = NS) noexcept;
static double short_code_check(TIME format = NS) noexcept;
static double common_code_check(TIME format = NS) noexcept;
static double raw_code_check_random(TIME format = NS) noexcept;
static double short_code_check_random(TIME format = NS) noexcept;
static double common_code_check_random(TIME format = NS) noexcept;
static double short_code_to_string(TIME format = NS) noexcept;
static double short_code_from_string(TIME format = NS) noexcept;
static double common_code_to_string(TIME format = NS) noexcept;
static double common_code_from_string(TIME format = NS) noexcept;
static double common_code_to_raw_code(TIME format = NS) noexcept;
static double raw_code_to_common_code(TIME format = NS) noexcept;
static double common_code_to_short_code(TIME format = US) noexcept;
static double short_code_to_common_code(TIME format = US) noexcept;
static double common_code_to_short_code_fast(TIME format = NS) noexcept;
static double short_code_to_common_code_fast(TIME format = NS) noexcept;
static double vertical_mirror_check(TIME format = NS) noexcept;
static double horizontal_mirror_check(TIME format = NS) noexcept;
static double vertical_mirror_convert(TIME format = NS) noexcept;
static double horizontal_mirror_convert(TIME format = NS) noexcept;
private:
static bool data_ready_;
static std::mutex data_building_;
static std::vector<RawCode> all_raw_codes_;
static std::vector<ShortCode> all_short_codes_;
static std::vector<CommonCode> all_common_codes_;
static std::vector<std::string> all_short_codes_str_;
static std::vector<std::string> all_common_codes_str_;
static void build_data() noexcept;
static uint32_t random_seed() noexcept;
static double time_format(clock_t start, TIME format) noexcept;
static std::vector<uint32_t> generate_u32_rand(uint32_t count) noexcept;
static std::vector<uint64_t> generate_u64_rand(uint32_t count) noexcept;
};
} // namespace klotski

68
src/klotski_core/benchmark/chore.cc

@ -2,18 +2,15 @@
#include <random> #include <random>
#include "benchmark.h" #include "benchmark.h"
using klotski::RawCode; namespace klotski {
using klotski::ShortCode;
using klotski::CommonCode; bool Benchmark::data_ready_ = false;
using klotski::Benchmark; std::mutex Benchmark::data_building_;
std::vector<RawCode> Benchmark::all_raw_codes_;
bool Benchmark::data_ready = false; std::vector<ShortCode> Benchmark::all_short_codes_;
std::mutex Benchmark::data_building; std::vector<CommonCode> Benchmark::all_common_codes_;
std::vector<RawCode> Benchmark::all_raw_codes; std::vector<std::string> Benchmark::all_short_codes_str_;
std::vector<ShortCode> Benchmark::all_short_codes; std::vector<std::string> Benchmark::all_common_codes_str_;
std::vector<CommonCode> Benchmark::all_common_codes;
std::vector<std::string> Benchmark::all_short_codes_str;
std::vector<std::string> Benchmark::all_common_codes_str;
uint32_t Benchmark::random_seed() noexcept { uint32_t Benchmark::random_seed() noexcept {
using namespace std::chrono; using namespace std::chrono;
@ -47,6 +44,7 @@ double Benchmark::time_format(clock_t start, TIME format) noexcept {
return time / CLOCKS_PER_SEC; return time / CLOCKS_PER_SEC;
} }
/// Generate a specified count of 32-bit random numbers.
std::vector<uint32_t> Benchmark::generate_u32_rand(uint32_t count) noexcept { std::vector<uint32_t> Benchmark::generate_u32_rand(uint32_t count) noexcept {
std::vector<uint32_t> result; std::vector<uint32_t> result;
result.reserve(count); result.reserve(count);
@ -56,71 +54,73 @@ std::vector<uint32_t> Benchmark::generate_u32_rand(uint32_t count) noexcept {
std::srand(seed); std::srand(seed);
for (uint32_t i = 0; i < count; ++i) { for (uint32_t i = 0; i < count; ++i) {
auto tmp = high_bit | static_cast<uint32_t>(std::rand()); auto tmp = high_bit | static_cast<uint32_t>(std::rand()); // int32_t -> uint32_t
result.emplace_back(tmp); result.emplace_back(tmp);
high_bit = tmp << 31; high_bit = tmp << 31;
} }
return result; return result;
} }
/// Generate a specified count of 64-bit random numbers.
std::vector<uint64_t> Benchmark::generate_u64_rand(uint32_t count) noexcept { std::vector<uint64_t> Benchmark::generate_u64_rand(uint32_t count) noexcept {
std::vector<uint64_t> result; std::vector<uint64_t> result;
result.reserve(count); result.reserve(count);
auto tmp = generate_u32_rand(count * 2); auto tmp = generate_u32_rand(count * 2);
for (uint32_t i = 0; i < count; ++i) { for (uint32_t i = 0; i < count; ++i) {
result.emplace_back((uint64_t)tmp[i * 2] << 32 | tmp[i * 2 + 1]); result.emplace_back((uint64_t)tmp[i * 2] << 32 | tmp[i * 2 + 1]); // combine two uint32_t
} }
return result; return result;
} }
void Benchmark::data_preparation() noexcept { void Benchmark::data_initialize() noexcept {
if (!Benchmark::data_ready) { if (!data_ready_) {
if (Benchmark::data_building.try_lock()) { // mutex lock success if (data_building_.try_lock()) { // mutex lock success
build_data(); // start build process build_data(); // start build process
Benchmark::data_ready = true; // set available flag data_ready_ = true;
} else { } else {
Benchmark::data_building.lock(); // blocking waiting data_building_.lock(); // blocking waiting
} }
Benchmark::data_building.unlock(); // release mutex data_building_.unlock(); // release mutex
} }
} }
void Benchmark::build_data() noexcept { void Benchmark::build_data() noexcept {
/// short code data preparation /// short code data preparation
std::vector<uint32_t> tmp(klotski::SHORT_CODE_LIMIT); std::vector<uint32_t> tmp(SHORT_CODE_LIMIT);
std::iota(tmp.begin(), tmp.end(), 0); std::iota(tmp.begin(), tmp.end(), 0);
all_short_codes.reserve(klotski::SHORT_CODE_LIMIT); all_short_codes_.reserve(SHORT_CODE_LIMIT);
for (auto &&short_code : tmp) { // 0 ~ (SHORT_CODE_LIMIT - 1) for (auto &&short_code : tmp) { // 0 ~ (SHORT_CODE_LIMIT - 1)
all_short_codes.emplace_back(ShortCode::unsafe_create(short_code)); all_short_codes_.emplace_back(ShortCode::unsafe_create(short_code));
} }
all_short_codes_str.reserve(klotski::SHORT_CODE_LIMIT); all_short_codes_str_.reserve(SHORT_CODE_LIMIT);
for (auto &&short_code : tmp) { // 0 ~ (SHORT_CODE_LIMIT - 1) for (auto &&short_code : tmp) { // 0 ~ (SHORT_CODE_LIMIT - 1)
all_short_codes_str.emplace_back( all_short_codes_str_.emplace_back(
ShortCode::unsafe_create(short_code).to_string() ShortCode::unsafe_create(short_code).to_string()
); );
} }
/// common code info preparation /// common code info preparation
all_common_codes.reserve(klotski::ALL_CASES_SIZE_SUM); all_common_codes_.reserve(ALL_CASES_SIZE_SUM);
for (uint64_t head = 0; head < 16; ++head) { for (uint64_t head = 0; head < 16; ++head) {
for (const auto &range : AllCases::fetch()[head]) { for (const auto &range : AllCases::fetch()[head]) {
all_common_codes.emplace_back( all_common_codes_.emplace_back(
CommonCode::unsafe_create(head << 32 | range) CommonCode::unsafe_create(head << 32 | range)
); );
} }
} }
all_common_codes_str.reserve(klotski::ALL_CASES_SIZE_SUM); all_common_codes_str_.reserve(ALL_CASES_SIZE_SUM);
for (auto &&common_code : all_common_codes) { for (auto &&common_code : all_common_codes_) {
all_common_codes_str.emplace_back(common_code.to_string()); all_common_codes_str_.emplace_back(common_code.to_string());
} }
/// raw code data preparation /// raw code data preparation
all_raw_codes.reserve(klotski::ALL_CASES_SIZE_SUM); all_raw_codes_.reserve(ALL_CASES_SIZE_SUM);
for (auto &&common_code : all_common_codes) { for (auto &&common_code : all_common_codes_) {
all_raw_codes.emplace_back(common_code.to_raw_code()); all_raw_codes_.emplace_back(common_code.to_raw_code());
} }
} }
} // namespace klotski

Loading…
Cancel
Save