Browse Source

perf: benchmark structure

legacy
Dnomd343 2 years ago
parent
commit
584d39d1c4
  1. 102
      src/klotski_core/benchmark/benchmark.cc
  2. 25
      src/klotski_core/benchmark/benchmark.h
  3. 55
      src/klotski_core/benchmark/chore.cc
  4. 5
      src/klotski_core/ffi/tmain.cc

102
src/klotski_core/benchmark/benchmark.cc

@ -1,11 +1,5 @@
#include <string>
#include <vector>
#include "benchmark.h" #include "benchmark.h"
#include "all_cases.h" #include "all_cases.h"
#include "short_code.h"
#include "common_code.h"
#include <iostream>
using klotski::Benchmark; using klotski::Benchmark;
@ -29,109 +23,45 @@ double Benchmark::all_cases(TIME format) noexcept {
} }
double Benchmark::short_code_to_string(TIME format) noexcept { double Benchmark::short_code_to_string(TIME format) noexcept {
/// data preparation if (!data_ready) {
std::vector<ShortCode> data; return -1; // data no ready -> skip
data.reserve(klotski::SHORT_CODE_LIMIT);
for (uint32_t short_code = 0; short_code < klotski::SHORT_CODE_LIMIT; ++short_code) {
data.emplace_back(ShortCode::unsafe_create(short_code));
} }
/// start benchmark
auto start = clock(); auto start = clock();
for (const auto &short_code : data) { for (const auto &short_code : all_short_codes) {
short_code.to_string(); short_code.to_string();
} }
return time_format(start, format) / (double)data.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 {
/// data preparation if (!data_ready) {
std::vector<std::string> data; return -1; // data no ready -> skip
data.reserve(klotski::SHORT_CODE_LIMIT);
for (uint32_t short_code = 0; short_code < klotski::SHORT_CODE_LIMIT; ++short_code) {
data.emplace_back(ShortCode::unsafe_create(short_code).to_string());
} }
/// start benchmark
auto start = clock(); auto start = clock();
for (auto &&short_code : data) { 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)data.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 {
/// data preparation if (!data_ready) {
std::vector<CommonCode> data; return -1; // data no ready -> skip
data.reserve(klotski::ALL_CASES_SIZE_SUM);
for (uint64_t head = 0; head < 16; ++head) {
for (const auto &range : AllCases::fetch()[head]) {
data.emplace_back(CommonCode::unsafe_create(head << 32 | range));
} }
}
/// start benchmark
auto start = clock(); auto start = clock();
for (const auto &common_code : data) { for (const auto &common_code : all_common_codes) {
common_code.to_string(); common_code.to_string();
} }
return time_format(start, format) / (double)data.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 {
/// data preparation if (!data_ready) {
std::vector<std::string> data; return -1; // data no ready -> skip
data.reserve(klotski::ALL_CASES_SIZE_SUM);
for (uint64_t head = 0; head < 16; ++head) {
for (const auto &range : AllCases::fetch()[head]) {
data.emplace_back(
CommonCode::unsafe_create(head << 32 | range).to_string()
);
}
}
/// start benchmark
auto start = clock();
for (auto &&common_code : data) {
CommonCode{std::forward<std::string>(common_code)};
}
return time_format(start, format) / (double)data.size();
} }
double Benchmark::common_code_to_string_shorten(TIME format) noexcept {
/// data preparation
std::vector<CommonCode> data;
data.reserve(klotski::ALL_CASES_SIZE_SUM);
for (uint64_t head = 0; head < 16; ++head) {
for (const auto &range : AllCases::fetch()[head]) {
data.emplace_back(CommonCode::unsafe_create(head << 32 | range));
}
}
/// start benchmark
auto start = clock();
for (const auto &common_code : data) {
common_code.to_string(true);
}
return time_format(start, format) / (double)data.size();
}
double Benchmark::common_code_from_string_shorten(TIME format) noexcept {
/// data preparation
std::vector<std::string> data;
data.reserve(klotski::ALL_CASES_SIZE_SUM);
for (uint64_t head = 0; head < 16; ++head) {
for (const auto &range : AllCases::fetch()[head]) {
data.emplace_back(
CommonCode::unsafe_create(head << 32 | range).to_string(true)
);
}
}
/// start benchmark
auto start = clock(); auto start = clock();
for (auto &&common_code : data) { 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)data.size(); return time_format(start, format) / (double)all_common_codes_str.size();
} }

25
src/klotski_core/benchmark/benchmark.h

@ -8,24 +8,30 @@
/// returned according to the specified time format (seconds, milliseconds, /// returned according to the specified time format (seconds, milliseconds,
/// microseconds, nanoseconds). /// microseconds, nanoseconds).
/// The test items are all multi-thread safe, but you should not run multiple /// The test items are all multi-thread safe(except `data_prepare`), but you
/// test items at the same time, which will lead to unstable tests in many ways, /// should not run multiple test items at the same time, which will lead to
/// such as changes in CPU turbo frequency. /// unstable tests in many ways, such as changes in CPU turbo frequency.
/// Pay attention to the two test items `basic_ranges` and `all_cases`, they can /// Pay attention to the two test items `basic_ranges` and `all_cases`, they can
/// only be run once (the reason for the construction of static data), and cannot /// only be run once (the reason for the construction of static data), and cannot
/// be run after other global related items. /// be run after other global related items.
#include <ctime> #include <ctime>
#include <string>
#include <vector>
#include <cstdint> #include <cstdint>
#include "raw_code.h"
#include "short_code.h"
#include "common_code.h"
namespace klotski { namespace klotski {
class Benchmark { class Benchmark {
public: public:
enum TIME { enum TIME {
S, MS, US, NS S, MS, US, NS
}; };
static uint32_t core_num() noexcept; static void data_preparation() noexcept;
static double warm_up(uint64_t count) noexcept; static double warm_up(uint64_t count) noexcept;
static double all_cases(TIME format = MS) noexcept; static double all_cases(TIME format = MS) noexcept;
@ -37,9 +43,6 @@ namespace klotski {
static double common_code_to_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_from_string(TIME format = NS) noexcept;
static double common_code_to_string_shorten(TIME format = NS) noexcept;
static double common_code_from_string_shorten(TIME format = NS) noexcept;
// static float codec_common_to_raw(TIME format = US); // static float codec_common_to_raw(TIME format = US);
// static float codec_raw_to_common(TIME format = US); // static float codec_raw_to_common(TIME format = US);
// static float codec_common_to_short(); // static float codec_common_to_short();
@ -47,8 +50,14 @@ namespace klotski {
// static float codec_common_to_short_fast(); // static float codec_common_to_short_fast();
// static float codec_short_to_common_fast(); // static float codec_short_to_common_fast();
private: private:
static bool data_ready;
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 double time_format(clock_t start, TIME format) noexcept; static double time_format(clock_t start, TIME format) noexcept;
}; };
} }

55
src/klotski_core/benchmark/chore.cc

@ -1,11 +1,17 @@
#include <thread> #include <thread>
#include "benchmark.h" #include "benchmark.h"
using klotski::RawCode;
using klotski::ShortCode;
using klotski::CommonCode;
using klotski::Benchmark; using klotski::Benchmark;
uint32_t Benchmark::core_num() noexcept { bool Benchmark::data_ready = false;
return std::thread::hardware_concurrency(); 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;
double Benchmark::warm_up(uint64_t count) noexcept { double Benchmark::warm_up(uint64_t count) noexcept {
auto start = clock(); auto start = clock();
@ -32,3 +38,46 @@ double Benchmark::time_format(clock_t start, TIME format) noexcept {
} }
return time / CLOCKS_PER_SEC; return time / CLOCKS_PER_SEC;
} }
void Benchmark::data_preparation() noexcept {
if (Benchmark::data_ready) {
return;
}
/// short code data preparation
std::vector<uint32_t> tmp(klotski::SHORT_CODE_LIMIT);
std::iota(tmp.begin(), tmp.end(), 0);
all_short_codes.reserve(klotski::SHORT_CODE_LIMIT);
for (auto &&short_code : tmp) {
all_short_codes.emplace_back(ShortCode::unsafe_create(short_code));
}
all_short_codes_str.reserve(klotski::SHORT_CODE_LIMIT);
for (auto &&short_code : all_short_codes) {
all_short_codes_str.emplace_back(short_code.to_string());
}
/// common code info preparation
all_common_codes.reserve(klotski::ALL_CASES_SIZE_SUM);
for (uint64_t head = 0; head < 16; ++head) {
for (const auto &range : AllCases::fetch()[head]) {
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());
}
/// 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());
}
Benchmark::data_ready = true;
}

5
src/klotski_core/ffi/tmain.cc

@ -21,15 +21,14 @@ void tmain() {
// std::cout << "basic ranges: " << Benchmark::basic_ranges() << "ms" << std::endl; // std::cout << "basic ranges: " << Benchmark::basic_ranges() << "ms" << std::endl;
// std::cout << "all cases: " << Benchmark::all_cases() << "ms" << std::endl; // std::cout << "all cases: " << Benchmark::all_cases() << "ms" << std::endl;
Benchmark::data_preparation();
std::cout << Benchmark::short_code_to_string() << "ns" << std::endl; std::cout << Benchmark::short_code_to_string() << "ns" << std::endl;
std::cout << Benchmark::short_code_from_string() << "ns" << std::endl; std::cout << Benchmark::short_code_from_string() << "ns" << std::endl;
std::cout << Benchmark::common_code_to_string() << "ns" << std::endl; std::cout << Benchmark::common_code_to_string() << "ns" << std::endl;
std::cout << Benchmark::common_code_from_string() << "ns" << std::endl; std::cout << Benchmark::common_code_from_string() << "ns" << std::endl;
std::cout << Benchmark::common_code_to_string_shorten() << "ns" << std::endl;
std::cout << Benchmark::common_code_from_string_shorten() << "ns" << std::endl;
return; return;
std::vector<uint64_t> next; std::vector<uint64_t> next;

Loading…
Cancel
Save