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(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();

2
src/core/group/group.h

@ -111,7 +111,7 @@ public:
using Groups = std::vector<Group>;
/// 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;

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 {
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<uint8_t>(mirror_type()) * 4;
const auto toward = towards[offset + static_cast<uint8_t>(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<uint8_t>(mirror_type()) * 4;
const auto toward = towards[offset + static_cast<uint8_t>(toward_)];
return unsafe_create(type_id_, pattern_id_, toward);
}
} // namespace klotski::group

24
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()) {

Loading…
Cancel
Save