Browse Source

perf: group mirror implementation

master
Dnomd343 2 weeks ago
parent
commit
7e0c75e2e2
  1. 51
      src/core/benchmark/group.cc
  2. 2
      src/core/group/group.h
  3. 99
      src/core/group/internal/group_mirror.inl
  4. 24
      src/core_test/group/group_pro.cc

51
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(CommonCodeToTypeId)->Arg(8)->Arg(64)->Arg(256);
// BENCHMARK(RawCodeToTypeId)->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(SpawnGroups);
BENCHMARK(GroupFromRawCode)->Unit(benchmark::kMillisecond); // BENCHMARK(GroupFromRawCode)->Unit(benchmark::kMillisecond);
// BENCHMARK(IsVerticalMirror);
// BENCHMARK(IsHorizontalMirror);
BENCHMARK(ToVerticalMirror);
BENCHMARK(ToHorizontalMirror);
BENCHMARK_MAIN(); BENCHMARK_MAIN();

2
src/core/group/group.h

@ -111,7 +111,7 @@ public:
using Groups = std::vector<Group>; using Groups = std::vector<Group>;
/// Get all groups under the current type id. /// 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. /// Get all klotski cases under the current type id.
[[nodiscard]] cases::RangesUnion cases() const; [[nodiscard]] cases::RangesUnion cases() const;

99
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 { constexpr bool Group::is_vertical_mirror() const {
switch (mirror_type()) { switch (mirror_type()) {
case MirrorType::Full: case MirrorType::Full: return true;
return true; case MirrorType::Horizontal: return false;
case MirrorType::Horizontal: case MirrorType::Centro: return false;
return false; case MirrorType::Vertical: return true;
case MirrorType::Centro: case MirrorType::Ordinary: return false;
return false;
case MirrorType::Vertical:
return true;
case MirrorType::Ordinary:
return false;
} }
std::unreachable();
} }
constexpr bool Group::is_horizontal_mirror() const { constexpr bool Group::is_horizontal_mirror() const {
switch (mirror_type()) { switch (mirror_type()) {
case MirrorType::Full: case MirrorType::Full: return true;
return true; case MirrorType::Horizontal: return true;
case MirrorType::Horizontal: case MirrorType::Centro: return false;
return true; case MirrorType::Vertical: return false;
case MirrorType::Centro: case MirrorType::Ordinary: return false;
return false;
case MirrorType::Vertical:
return false;
case MirrorType::Ordinary:
return false;
} }
std::unreachable();
} }
constexpr Group Group::to_vertical_mirror() const { constexpr Group Group::to_vertical_mirror() const {
switch (mirror_type()) { constexpr auto nil {Toward::A}; // placeholder
case MirrorType::Full: constexpr auto towards = std::to_array({
return *this; Toward::A, nil, nil, nil, // MirrorType::Full
case MirrorType::Horizontal: Toward::C, nil, Toward::A, nil, // MirrorType::Horizontal
if (toward_ == Toward::A) { Toward::B, Toward::A, nil, nil, // MirrorType::Centro
return Group::unsafe_create(type_id_, pattern_id_, Toward::C); Toward::A, Toward::B, nil, nil, // MirrorType::Vertical
} Toward::C, Toward::D, Toward::A, Toward::B, // MirrorType::Ordinary
return Group::unsafe_create(type_id_, pattern_id_, Toward::A); });
case MirrorType::Centro: const auto offset = static_cast<uint8_t>(mirror_type()) * 4;
if (toward_ == Toward::A) { const auto toward = towards[offset + static_cast<uint8_t>(toward_)];
return Group::unsafe_create(type_id_, pattern_id_, Toward::B); return unsafe_create(type_id_, pattern_id_, toward);
}
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 Group Group::to_horizontal_mirror() const { constexpr Group Group::to_horizontal_mirror() const {
switch (mirror_type()) { constexpr auto nil {Toward::A}; // placeholder
case MirrorType::Full: constexpr auto towards = std::to_array({
case MirrorType::Horizontal: Toward::A, nil, nil, nil, // MirrorType::Full
return *this; Toward::A, nil, Toward::C, nil, // MirrorType::Horizontal
case MirrorType::Centro: Toward::B, Toward::A, nil, nil, // MirrorType::Centro
case MirrorType::Vertical: Toward::B, Toward::A, nil, nil, // MirrorType::Vertical
if (toward_ == Toward::A) { Toward::B, Toward::A, Toward::D, Toward::C, // MirrorType::Ordinary
return Group::unsafe_create(type_id_, pattern_id_, Toward::B); });
} const auto offset = static_cast<uint8_t>(mirror_type()) * 4;
return Group::unsafe_create(type_id_, pattern_id_, Toward::A); const auto toward = towards[offset + static_cast<uint8_t>(toward_)];
case MirrorType::Ordinary: return unsafe_create(type_id_, pattern_id_, toward);
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);
}
} }
} // namespace klotski::group } // namespace klotski::group

24
src/core_test/group/group_pro.cc

@ -10,30 +10,6 @@
using klotski::group::Group; using klotski::group::Group;
using klotski::group::GroupUnion; 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) { TEST(Group, cases) {
GROUP_UNION_PARALLEL({ GROUP_UNION_PARALLEL({
for (auto group : group_union.groups()) { for (auto group : group_union.groups()) {

Loading…
Cancel
Save