#include <algorithm>
#include <queue>
#include <vector>
const int slow_size = 10000;
const int fast_size = 1000000;
{
protected:
std::vector<int> items;
{
items.resize(context.
x());
}
{
items.clear();
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
for (size_t i = 0; i < items.size(); ++i)
{
size_t min = i;
for (size_t j = i + 1; j < items.size(); ++j)
{
if (items[j] < items[min])
min = j;
}
std::swap(items[i], items[min]);
}
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
for (size_t i = 0; i < items.size(); ++i)
{
size_t bound = items.size() - i;
for (size_t j = 1; j < bound; ++j)
{
if (items[j] < items[j - 1])
std::swap(items[j], items[j - 1]);
}
}
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
size_t left = 1;
size_t right = items.size();
while (left < right)
{
for (size_t i = right; i > left; --i)
{
if (items[i - 1] < items[i - 1 - 1])
std::swap(items[i - 1], items[i - 1 - 1]);
}
++left;
for (size_t i = left; i < right; ++i)
{
if (items[i + 1 - 1] < items[i - 1])
std::swap(items[i + 1 - 1], items[i - 1]);
}
--right;
}
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
size_t i = 1;
size_t j = 2;
while (i < items.size())
{
if (items[i] < items[i - 1])
{
std::swap(items[i], items[i - 1]);
--i;
if (i == 0)
{
i = j;
++j;
}
}
else
{
i = j;
++j;
}
}
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
for (size_t i = 1; i < items.size(); ++i)
{
for (size_t j = i + 1; j > 1; --j)
{
if (items[j - 1] < items[j - 1 - 1])
std::swap(items[j - 1], items[j - 1 - 1]);
}
}
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
size_t d = 1;
while (d < items.size())
d = 3 * d + 1;
while (d > 0)
{
ShellSortInternal(items, d);
d /= 3;
}
}
private:
void ShellSortInternal(std::vector<int>& subitems, size_t d) const
{
for (size_t i = d; i < subitems.size(); ++i)
{
for (size_t j = i + 1; j >= d + 1; j -= d)
{
if (subitems[j - 1] < subitems[j - d - 1])
std::swap(subitems[j - 1], subitems[j - d - 1]);
}
}
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
std::vector<int> temp(items.size());
size_t chunk = 1;
while (chunk < items.size())
{
for (size_t i = 0; i < items.size(); i += 2 * chunk)
MergeSortInternal(temp.data() + i, items.data() + i, i, items.size(), chunk);
chunk *= 2;
std::swap(temp, items);
}
}
private:
static void MergeSortInternal(int* dst, int* src, size_t index, size_t size, size_t chunk)
{
size_t index1 = 0;
size_t index2 = 0;
while ((index1 < chunk) || (index2 < chunk))
{
if ((index + index1 >= size))
index1 = chunk;
if (index + chunk + index2 >= size)
index2 = chunk;
if ((index2 < chunk) && ((index1 == chunk) || (src[chunk + index2] < src[index1])))
{
*dst++ = src[chunk + index2];
++index2;
}
else if (index1 < chunk)
{
*dst++ = src[index1];
++index1;
}
}
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
if (items.size() > 0)
QuickSortInternal(items, 1, items.size());
}
private:
static void QuickSortInternal(std::vector<int>& subitems, size_t left, size_t right)
{
int pivot = subitems[left + ((right - left) / 2) - 1];
size_t l = left;
size_t r = right;
while (l <= r)
{
while ((l < right) && (subitems[l - 1] < pivot))
l++;
while ((r > left) && (subitems[r - 1] > pivot))
r--;
if (l <= r)
{
std::swap(subitems[l - 1], subitems[r - 1]);
++l;
--r;
}
}
if (left < r)
QuickSortInternal(subitems, left, r);
if (l < right)
QuickSortInternal(subitems, l, right);
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
if (items.size() > 0)
QuickSort3Internal(items, 1, items.size());
}
private:
static void QuickSort3Internal(std::vector<int>& subitems, size_t left, size_t right)
{
int pivot = subitems[left + ((right - left) / 2) - 1];
size_t bl = left;
size_t br = right;
size_t l = left;
size_t r = right;
while (l <= r)
{
while ((l < right) && (subitems[l - 1] < pivot))
l++;
while ((r > left) && (subitems[r - 1] > pivot))
r--;
if (l <= r)
{
std::swap(subitems[l - 1], subitems[r - 1]);
if (subitems[l - 1] == pivot)
{
std::swap(subitems[bl - 1], subitems[l - 1]);
bl++;
}
if (subitems[r - 1] == pivot)
{
std::swap(subitems[br - 1], subitems[r - 1]);
br++;
}
++l;
--r;
}
}
for (size_t k = left; (k < bl) && (r > left); ++k, --r)
std::swap(subitems[k - 1], subitems[r - 1]);
for (size_t k = right; (k > br) && (l < right); --k, ++l)
std::swap(subitems[k - 1], subitems[l - 1]);
if (left < r)
QuickSort3Internal(subitems, left, r);
if (l < right)
QuickSort3Internal(subitems, l, right);
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
std::queue<int> radix_queue[10];
size_t n = 1;
bool found;
do
{
found = false;
for (size_t i = 0; i < items.size(); ++i)
{
size_t base = items[i] / n;
found |= base > 0;
size_t index = base % 10;
radix_queue[index].push(items[i]);
}
if (found)
{
size_t index = 0;
for (size_t i = 0; i < sizeof(radix_queue) / sizeof(radix_queue[0]); ++i)
{
while (!radix_queue[i].empty())
{
items[index++] = radix_queue[i].front();
radix_queue[i].pop();
}
}
}
n *= 10;
} while (found);
}
};
{
public:
protected:
{
std::generate(items.begin(), items.end(), rand);
std::sort(items.begin(), items.end());
}
};
BENCHMARK_CLASS(SelectionSort,
"SelectionSort", Settings().Param(slow_size))
Benchmark(const std::string &name, Types... settings)
Default class constructor.
virtual void Run(Context &context)=0
Benchmark run method.
Benchmark running context.
int x() const noexcept
Benchmark first parameter. Valid only if not negative!
PhaseMetrics & metrics() noexcept
Benchmark mutable metrics.
virtual void Initialize(Context &context)
Initialize benchmark.
virtual void Cleanup(Context &context)
Cleanup benchmark.
void AddItems(int64_t items) noexcept
Register processed items in the current phase.
CppBenchmark definitions.
#define BENCHMARK_CLASS(type,...)
Benchmark class register macro.
#define BENCHMARK_MAIN()
Benchmark main entry point macro.