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 ---------------------------
double Benchmark::raw_code_check(TIME format) noexcept {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&raw_code : all_raw_codes) {
for (auto &&raw_code : all_raw_codes_) {
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&short_code : all_short_codes) {
for (auto &&short_code : all_short_codes_) {
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&common_code : all_common_codes) {
for (auto &&common_code : all_common_codes_) {
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 {
@ -108,167 +108,167 @@ double Benchmark::common_code_check_random(TIME format) noexcept {
/// -------------------------- Benchmark Code String --------------------------
double Benchmark::short_code_to_string(TIME format) noexcept {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&short_code : all_short_codes) {
for (auto &&short_code : all_short_codes_) {
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
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)};
}
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&common_code : all_common_codes) {
for (auto &&common_code : all_common_codes_) {
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
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)};
}
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 --------------------------
double Benchmark::common_code_to_raw_code(TIME format) noexcept {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&common_code : all_common_codes) {
for (auto &&common_code : all_common_codes_) {
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&raw_code : all_raw_codes) {
for (auto &&raw_code : all_raw_codes_) {
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
uint32_t num = 0;
ShortCode::speed_up(ShortCode::NORMAL);
auto start = clock();
for (uint64_t i = 0; i < all_common_codes.size(); i += 1000) {
ShortCode{all_common_codes[i]};
for (uint64_t i = 0; i < all_common_codes_.size(); i += 1000) {
ShortCode{all_common_codes_[i]};
++num;
}
return time_format(start, format) / (double)num;
}
double Benchmark::short_code_to_common_code(TIME format) noexcept {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
uint32_t num = 0;
ShortCode::speed_up(ShortCode::NORMAL);
auto start = clock();
for (uint64_t i = 0; i < all_short_codes.size(); i += 1000) {
all_short_codes[i].to_common_code();
for (uint64_t i = 0; i < all_short_codes_.size(); i += 1000) {
all_short_codes_[i].to_common_code();
++num;
}
return time_format(start, format) / (double)num;
}
double Benchmark::common_code_to_short_code_fast(TIME format) noexcept {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
ShortCode::speed_up(ShortCode::FAST);
auto start = clock();
for (auto &&common_code : all_common_codes) {
for (auto &&common_code : all_common_codes_) {
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
ShortCode::speed_up(ShortCode::FAST);
auto start = clock();
for (auto &&short_code : all_short_codes) {
for (auto &&short_code : all_short_codes_) {
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 -----------------------------
double Benchmark::vertical_mirror_check(TIME format) noexcept {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&raw_code : all_raw_codes) {
for (auto &&raw_code : all_raw_codes_) {
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&raw_code : all_raw_codes) {
for (auto &&raw_code : all_raw_codes_) {
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&raw_code : all_raw_codes) {
for (auto &&raw_code : all_raw_codes_) {
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 {
if (!data_ready) {
if (!data_ready_) {
return -1; // data no ready -> skip
}
auto start = clock();
for (auto &&raw_code : all_raw_codes) {
for (auto &&raw_code : all_raw_codes_) {
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"
namespace klotski {
class Benchmark {
public:
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;
class Benchmark {
public:
enum TIME {
S, MS, US, NS
};
}
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 "benchmark.h"
using klotski::RawCode;
using klotski::ShortCode;
using klotski::CommonCode;
using klotski::Benchmark;
bool Benchmark::data_ready = false;
std::mutex Benchmark::data_building;
std::vector<RawCode> Benchmark::all_raw_codes;
std::vector<ShortCode> Benchmark::all_short_codes;
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;
namespace klotski {
bool Benchmark::data_ready_ = false;
std::mutex Benchmark::data_building_;
std::vector<RawCode> Benchmark::all_raw_codes_;
std::vector<ShortCode> Benchmark::all_short_codes_;
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 {
using namespace std::chrono;
@ -47,6 +44,7 @@ double Benchmark::time_format(clock_t start, TIME format) noexcept {
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> result;
result.reserve(count);
@ -56,71 +54,73 @@ std::vector<uint32_t> Benchmark::generate_u32_rand(uint32_t count) noexcept {
std::srand(seed);
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);
high_bit = tmp << 31;
}
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> result;
result.reserve(count);
auto tmp = generate_u32_rand(count * 2);
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;
}
void Benchmark::data_preparation() noexcept {
if (!Benchmark::data_ready) {
if (Benchmark::data_building.try_lock()) { // mutex lock success
void Benchmark::data_initialize() noexcept {
if (!data_ready_) {
if (data_building_.try_lock()) { // mutex lock success
build_data(); // start build process
Benchmark::data_ready = true; // set available flag
data_ready_ = true;
} 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 {
/// 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);
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)
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)
all_short_codes_str.emplace_back(
all_short_codes_str_.emplace_back(
ShortCode::unsafe_create(short_code).to_string()
);
}
/// 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 (const auto &range : AllCases::fetch()[head]) {
all_common_codes.emplace_back(
all_common_codes_.emplace_back(
CommonCode::unsafe_create(head << 32 | range)
);
}
}
all_common_codes_str.reserve(klotski::ALL_CASES_SIZE_SUM);
for (auto &&common_code : all_common_codes) {
all_common_codes_str.emplace_back(common_code.to_string());
all_common_codes_str_.reserve(ALL_CASES_SIZE_SUM);
for (auto &&common_code : all_common_codes_) {
all_common_codes_str_.emplace_back(common_code.to_string());
}
/// raw code data preparation
all_raw_codes.reserve(klotski::ALL_CASES_SIZE_SUM);
for (auto &&common_code : all_common_codes) {
all_raw_codes.emplace_back(common_code.to_raw_code());
all_raw_codes_.reserve(ALL_CASES_SIZE_SUM);
for (auto &&common_code : all_common_codes_) {
all_raw_codes_.emplace_back(common_code.to_raw_code());
}
}
} // namespace klotski

Loading…
Cancel
Save