More efficient set_partition for C++ benchmark (#117)

* More efficient set_partition

Avoids some excess allocations. Still much slower than it could be, but this is trivial cleanup.

* ran clang format
pull/121/head^2
Stephen Berry 2022-12-18 12:12:19 -06:00 committed by GitHub
parent 8f36b710c8
commit d49212373c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 19 additions and 17 deletions

View File

@ -3,10 +3,9 @@
#include <iostream>
#include <vector>
#define vec std::vector
template <class T> using vec = std::vector<T>;
namespace {
vec<int> range(int start, int stop) {
inline vec<int> range(int start, int stop) {
vec<int> v(stop - start);
uint j = 0;
for (int i = start; i < stop; i++)
@ -14,19 +13,20 @@ vec<int> range(int start, int stop) {
return v;
}
bool conforms(const vec<vec<int>> &candidate, int minsize, int forgive) {
inline bool conforms(const vec<vec<int>> &candidate, int minsize, int forgive) {
int deficit = 0;
for (const auto &p : candidate) {
int need = minsize - p.size();
int need = minsize - static_cast<int>(p.size());
if (need > 0)
deficit += need;
}
return deficit <= forgive;
}
void partition_filtered(const vec<int> &collection,
std::function<void(const vec<vec<int>> &)> callback,
int minsize = 1, int forgive = 0) {
inline void
partition_filtered(const vec<int> &collection,
std::function<void(const vec<vec<int>> &)> callback,
int minsize = 1, int forgive = 0) {
if (collection.size() == 1) {
callback({collection});
return;
@ -35,13 +35,17 @@ void partition_filtered(const vec<int> &collection,
auto first = collection[0];
auto loop = [&](const vec<vec<int>> &smaller) {
int n = 0;
for (const auto &subset : smaller) {
vec<vec<int>> candidate;
candidate.reserve(smaller.size());
for (int i = 0; i < n; i++)
candidate.push_back(smaller[i]);
vec<int> rep;
vec<vec<int>> candidate;
candidate.reserve(smaller.size() + 1);
vec<int> rep;
for (const auto &subset : smaller) {
candidate.resize(n);
for (int i = 0; i < n; i++)
candidate[i] = smaller[i];
rep.clear();
rep.reserve(subset.size() + 1);
rep.push_back(first);
rep.insert(rep.end(), subset.begin(), subset.end());
@ -55,8 +59,7 @@ void partition_filtered(const vec<int> &collection,
++n;
}
vec<vec<int>> candidate;
candidate.reserve(smaller.size() + 1);
candidate.clear();
candidate.push_back({first});
candidate.insert(candidate.end(), smaller.begin(), smaller.end());
@ -67,7 +70,6 @@ void partition_filtered(const vec<int> &collection,
vec<int> new_collection(collection.begin() + 1, collection.end());
partition_filtered(new_collection, loop, minsize, forgive + 1);
}
} // namespace
int main(int argc, char *argv[]) {
using clock = std::chrono::high_resolution_clock;