From 7e0c75e2e2a2ab9f91000825bc2817803a38877d Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 3 Nov 2024 11:03:23 +0800 Subject: [PATCH] perf: group mirror implementation --- src/core/benchmark/group.cc | 51 +++++++++++- src/core/group/group.h | 2 +- src/core/group/internal/group_mirror.inl | 99 ++++++++---------------- src/core_test/group/group_pro.cc | 24 ------ 4 files changed, 85 insertions(+), 91 deletions(-) diff --git a/src/core/benchmark/group.cc b/src/core/benchmark/group.cc index 37fe2fc..9eebc64 100644 --- a/src/core/benchmark/group.cc +++ b/src/core/benchmark/group.cc @@ -278,6 +278,50 @@ static void GroupFromRawCode(benchmark::State &state) { } +static void IsVerticalMirror(benchmark::State &state) { + volatile int type_id = 169; + const auto groups = GroupUnion::unsafe_create(type_id).groups(); + + for (auto _ : state) { + for (auto group : groups) { + volatile auto kk = group.is_vertical_mirror(); + } + } +} + +static void IsHorizontalMirror(benchmark::State &state) { + volatile int type_id = 169; + const auto groups = GroupUnion::unsafe_create(type_id).groups(); + + for (auto _ : state) { + for (auto group : groups) { + volatile auto kk = group.is_horizontal_mirror(); + } + } +} + +static void ToVerticalMirror(benchmark::State &state) { + volatile int type_id = 169; + const auto groups = GroupUnion::unsafe_create(type_id).groups(); + + for (auto _ : state) { + for (auto group : groups) { + volatile auto kk = group.to_vertical_mirror(); + } + } +} + +static void ToHorizontalMirror(benchmark::State &state) { + volatile int type_id = 169; + const auto groups = GroupUnion::unsafe_create(type_id).groups(); + + for (auto _ : state) { + for (auto group : groups) { + volatile auto kk = group.to_horizontal_mirror(); + } + } +} + // BENCHMARK(CommonCodeToTypeId)->Arg(8)->Arg(64)->Arg(256); // BENCHMARK(RawCodeToTypeId)->Arg(8)->Arg(64)->Arg(256); @@ -295,6 +339,11 @@ static void GroupFromRawCode(benchmark::State &state) { // BENCHMARK(SpawnGroups); -BENCHMARK(GroupFromRawCode)->Unit(benchmark::kMillisecond); +// BENCHMARK(GroupFromRawCode)->Unit(benchmark::kMillisecond); + +// BENCHMARK(IsVerticalMirror); +// BENCHMARK(IsHorizontalMirror); +BENCHMARK(ToVerticalMirror); +BENCHMARK(ToHorizontalMirror); BENCHMARK_MAIN(); diff --git a/src/core/group/group.h b/src/core/group/group.h index 8e076b4..44f69dc 100644 --- a/src/core/group/group.h +++ b/src/core/group/group.h @@ -111,7 +111,7 @@ public: using Groups = std::vector; /// Get all groups under the current type id. - [[nodiscard]] constexpr Groups groups() const; + [[nodiscard]] constexpr Groups groups() const; // TODO: constexpr not support `std::vector` /// Get all klotski cases under the current type id. [[nodiscard]] cases::RangesUnion cases() const; diff --git a/src/core/group/internal/group_mirror.inl b/src/core/group/internal/group_mirror.inl index 47fb3d8..569a7b9 100644 --- a/src/core/group/internal/group_mirror.inl +++ b/src/core/group/internal/group_mirror.inl @@ -8,83 +8,52 @@ constexpr auto Group::mirror_type() const -> MirrorType { constexpr bool Group::is_vertical_mirror() const { switch (mirror_type()) { - case MirrorType::Full: - return true; - case MirrorType::Horizontal: - return false; - case MirrorType::Centro: - return false; - case MirrorType::Vertical: - return true; - case MirrorType::Ordinary: - return false; + case MirrorType::Full: return true; + case MirrorType::Horizontal: return false; + case MirrorType::Centro: return false; + case MirrorType::Vertical: return true; + case MirrorType::Ordinary: return false; } + std::unreachable(); } constexpr bool Group::is_horizontal_mirror() const { switch (mirror_type()) { - case MirrorType::Full: - return true; - case MirrorType::Horizontal: - return true; - case MirrorType::Centro: - return false; - case MirrorType::Vertical: - return false; - case MirrorType::Ordinary: - return false; + case MirrorType::Full: return true; + case MirrorType::Horizontal: return true; + case MirrorType::Centro: return false; + case MirrorType::Vertical: return false; + case MirrorType::Ordinary: return false; } + std::unreachable(); } constexpr Group Group::to_vertical_mirror() const { - switch (mirror_type()) { - case MirrorType::Full: - return *this; - case MirrorType::Horizontal: - if (toward_ == Toward::A) { - return Group::unsafe_create(type_id_, pattern_id_, Toward::C); - } - return Group::unsafe_create(type_id_, pattern_id_, Toward::A); - case MirrorType::Centro: - if (toward_ == Toward::A) { - return Group::unsafe_create(type_id_, pattern_id_, Toward::B); - } - return Group::unsafe_create(type_id_, pattern_id_, Toward::A); - case MirrorType::Vertical: - return *this; - case MirrorType::Ordinary: - if (toward_ == Toward::A) { - return Group::unsafe_create(type_id_, pattern_id_, Toward::C); - } else if (toward_ == Toward::B) { - return Group::unsafe_create(type_id_, pattern_id_, Toward::D); - } else if (toward_ == Toward::C) { - return Group::unsafe_create(type_id_, pattern_id_, Toward::A); - } - return Group::unsafe_create(type_id_, pattern_id_, Toward::B); - } + constexpr auto nil {Toward::A}; // placeholder + constexpr auto towards = std::to_array({ + Toward::A, nil, nil, nil, // MirrorType::Full + Toward::C, nil, Toward::A, nil, // MirrorType::Horizontal + Toward::B, Toward::A, nil, nil, // MirrorType::Centro + Toward::A, Toward::B, nil, nil, // MirrorType::Vertical + Toward::C, Toward::D, Toward::A, Toward::B, // MirrorType::Ordinary + }); + const auto offset = static_cast(mirror_type()) * 4; + const auto toward = towards[offset + static_cast(toward_)]; + return unsafe_create(type_id_, pattern_id_, toward); } constexpr Group Group::to_horizontal_mirror() const { - switch (mirror_type()) { - case MirrorType::Full: - case MirrorType::Horizontal: - return *this; - case MirrorType::Centro: - case MirrorType::Vertical: - if (toward_ == Toward::A) { - return Group::unsafe_create(type_id_, pattern_id_, Toward::B); - } - return Group::unsafe_create(type_id_, pattern_id_, Toward::A); - case MirrorType::Ordinary: - if (toward_ == Toward::A) { - return Group::unsafe_create(type_id_, pattern_id_, Toward::B); - } else if (toward_ == Toward::B) { - return Group::unsafe_create(type_id_, pattern_id_, Toward::A); - } else if (toward_ == Toward::C) { - return Group::unsafe_create(type_id_, pattern_id_, Toward::D); - } - return Group::unsafe_create(type_id_, pattern_id_, Toward::C); - } + constexpr auto nil {Toward::A}; // placeholder + constexpr auto towards = std::to_array({ + Toward::A, nil, nil, nil, // MirrorType::Full + Toward::A, nil, Toward::C, nil, // MirrorType::Horizontal + Toward::B, Toward::A, nil, nil, // MirrorType::Centro + Toward::B, Toward::A, nil, nil, // MirrorType::Vertical + Toward::B, Toward::A, Toward::D, Toward::C, // MirrorType::Ordinary + }); + const auto offset = static_cast(mirror_type()) * 4; + const auto toward = towards[offset + static_cast(toward_)]; + return unsafe_create(type_id_, pattern_id_, toward); } } // namespace klotski::group diff --git a/src/core_test/group/group_pro.cc b/src/core_test/group/group_pro.cc index b9c4909..3c35fe3 100644 --- a/src/core_test/group/group_pro.cc +++ b/src/core_test/group/group_pro.cc @@ -10,30 +10,6 @@ using klotski::group::Group; using klotski::group::GroupUnion; -TEST(Group, demo) { - - std::cout << helper::group_union_num() << std::endl; - - std::cout << helper::group_union_pattern_num(169) << std::endl; - std::cout << GroupUnion::unsafe_create(169).pattern_num() << std::endl; - - std::cout << helper::group_union_group_num(169) << std::endl; - std::cout << GroupUnion::unsafe_create(169).group_num() << std::endl; - - std::cout << (int)helper::pattern_mirror_type(169, 0) << std::endl; - std::cout << (int)Group::unsafe_create(169, 0, Group::Toward::A).mirror_type() << std::endl; - - std::cout << std::format("{}", helper::pattern_toward_list(169, 0)) << std::endl; - std::cout << (int)GroupUnion::unsafe_create(169).groups()[0].toward() << std::endl; - std::cout << (int)GroupUnion::unsafe_create(169).groups()[1].toward() << std::endl; - - auto group_1 = GroupUnion::unsafe_create(169).groups()[0]; - EXPECT_EQ(group_1.cases().codes(), helper::group_cases(169, 0, (uint32_t)group_1.toward())); - auto group_2 = GroupUnion::unsafe_create(169).groups()[1]; - EXPECT_EQ(group_2.cases().codes(), helper::group_cases(169, 0, (uint32_t)group_2.toward())); - -} - TEST(Group, cases) { GROUP_UNION_PARALLEL({ for (auto group : group_union.groups()) {