From 05ee6562a4c10895c28e0679bd875b9cc702dbee Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 18 Jan 2025 15:44:22 +0800 Subject: [PATCH] feat: mirror optimize demo of group cases --- src/core/benchmark/group.cc | 10 +++-- src/core/group/internal/group.cc | 69 ++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/core/benchmark/group.cc b/src/core/benchmark/group.cc index 28f48d1..be69e05 100644 --- a/src/core/benchmark/group.cc +++ b/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); diff --git a/src/core/group/internal/group.cc b/src/core/group/internal/group.cc index f0aa4e7..c11b824 100644 --- a/src/core/group/internal/group.cc +++ b/src/core/group/internal/group.cc @@ -1,3 +1,4 @@ +#include #include #include "group/group.h" @@ -48,6 +49,64 @@ static std::vector 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 codes; + // TODO: key type of flat_hash_map can using `RawCode` directly + phmap::flat_hash_map cases; // + codes.reserve(reserve); + cases.reserve(reserve * 1.56); + + std::vector 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(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(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()); }