Browse Source

feat: mirror optimize demo of group cases

master
Dnomd343 5 days ago
parent
commit
05ee6562a4
  1. 10
      src/core/benchmark/group.cc
  2. 69
      src/core/group/internal/group.cc

10
src/core/benchmark/group.cc

@ -112,10 +112,14 @@ static void RawCodeToTypeId(benchmark::State &state) {
static void GroupExtend(benchmark::State &state) {
auto src = klotski::codec::RawCode::from_common_code(0x1A9BF0C00).value();
// auto src = klotski::codec::RawCode::from_common_code(0x1A9BF0C00).value();
const auto group = Group::unsafe_create(169, 0, Group::Toward::C);
for (auto _ : state) {
volatile auto tmp = group.cases();
// volatile auto ret = klotski::group::Group_extend(src, 0);
// std::cout << ret.size() << std::endl;
@ -398,7 +402,7 @@ static void FastObtainCode(benchmark::State &state) {
// BENCHMARK(CommonCodeToTypeId)->Arg(8)->Arg(64)->Arg(256);
// BENCHMARK(RawCodeToTypeId)->Arg(8)->Arg(64)->Arg(256);
// BENCHMARK(GroupExtend)->Unit(benchmark::kMillisecond);
BENCHMARK(GroupExtend)->Unit(benchmark::kMillisecond);
// BENCHMARK(FilterFromAllCases)->Unit(benchmark::kMillisecond);
@ -414,7 +418,7 @@ static void FastObtainCode(benchmark::State &state) {
// BENCHMARK(GroupFromRawCode)->Unit(benchmark::kMillisecond);
BENCHMARK(FastObtainCode);
// BENCHMARK(FastObtainCode);
// BENCHMARK(IsVerticalMirror);
// BENCHMARK(IsHorizontalMirror);

69
src/core/group/internal/group.cc

@ -1,3 +1,4 @@
#include <iostream>
#include <algorithm>
#include "group/group.h"
@ -48,6 +49,64 @@ static std::vector<RawCode> Group_extend_for_cases(RawCode raw_code, uint32_t re
return codes;
}
// TODO: maybe we can send callback here (for GroupCases `data_1` builder)
static RangesUnion extend_demo(Group group, RawCode seed, size_t reserve) { // TODO: group param only for test
std::vector<RawCode> codes;
// TODO: key type of flat_hash_map can using `RawCode` directly
phmap::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
codes.reserve(reserve);
cases.reserve(reserve * 1.56);
std::vector<RawCode> mirror_codes;
mirror_codes.reserve(reserve); // TODO: cal max size-coff
auto core = MaskMover([&codes, &cases, &mirror_codes](RawCode code, uint64_t mask) {
// TODO: using `try_emplace` interface
if (const auto match = cases.find(code.unwrap()); match != cases.end()) {
match->second |= mask; // update mask
return;
}
cases.emplace(code, mask);
codes.emplace_back(code); // new case
auto kk = code.to_horizontal_mirror();
// if (const auto match = cases.find(kk.unwrap()); match != cases.end()) {
// return;
// }
// cases.emplace(kk, 0);
if (kk != code && cases.try_emplace(kk.unwrap(), 0).second) {
mirror_codes.emplace_back(kk);
}
});
uint64_t offset = 0;
codes.emplace_back(seed);
cases.emplace(seed, 0); // without mask
auto pp = seed.to_horizontal_mirror();
if (pp != seed) {
mirror_codes.emplace_back(seed.to_horizontal_mirror());
cases.emplace(seed.to_horizontal_mirror(), 0);
}
while (offset != codes.size()) {
auto curr = codes[offset++].unwrap();
core.next_cases(RawCode::unsafe_create(curr), cases.find(curr)->second);
}
std::cout << std::format("{}: {}+{}/{} ({})\n", group.to_string(), codes.size(), mirror_codes.size(), cases.size(), codes.size() + mirror_codes.size() == cases.size());
// TODO: we can emplace mirrored code into another vector
RangesUnion result {};
for (auto [raw_code, _] : cases) {
auto common_code = RawCode::unsafe_create(raw_code).to_common_code().unwrap();
result.ranges(common_code >> 32).emplace_back(static_cast<uint32_t>(common_code));
}
return result;
}
// TODO: maybe we can perf with mirror cases
RangesUnion Group::cases() const {
@ -66,14 +125,8 @@ RangesUnion Group::cases() const {
seed = seed.to_vertical_mirror().to_horizontal_mirror();
}
auto codes = Group_extend_for_cases(seed.to_raw_code(), size());
RangesUnion data;
for (auto raw_code : codes) {
auto common_code = raw_code.to_common_code().unwrap();
data.ranges(common_code >> 32).emplace_back(static_cast<uint32_t>(common_code));
}
// std::cout << seed << std::endl;
auto data = extend_demo(*this, seed.to_raw_code(), size());
for (int head = 0; head < 16; ++head) {
std::stable_sort(data.ranges(head).begin(), data.ranges(head).end());
}

Loading…
Cancel
Save