1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#include <algorithm>
#include <chrono>
#include <iostream>
#include <memory>
#include <random>
#include <vector>
#include <utility>
enum Opts {OPTA, OPTB, OPTC};
int compare(char c1, char c2) {
if (c1 > c2) return 1;
if (c1 < c2) return -1;
return 0;
}
bool compare1(const char* s1, const char* s2, size_t l) {
if (s1 != s2)
for (size_t i1 {}; i1 < l; ++i1)
if (const auto res { compare(s1[i1], s2[i1]) }; res)
return res > 0;
return false;
}
bool compare2(const char* s1, const char* s2, size_t l) {
if (s1 != s2)
for (size_t i1 {}; i1 < l; ++i1)
if (const auto res { compare(s1[i1], s2[i1]) }; res)
return res < 0;
return false;
}
auto setOpt(Opts opt) {
switch (opt) {
case OPTA:
case OPTB:
return std::pair<size_t, size_t>{1 << 24, 1 << 29};
case OPTC:
return std::pair<size_t, size_t> {1 << 18, 1 << 14};
default:
return std::pair<size_t, size_t>{0, 0};
}
}
auto init(auto opt, auto& s, auto L, auto N) {
std::minstd_rand rgen;
switch (opt) {
case OPTA:
std::cout << "Option A\n";
for (char *p { s.get() }, *end { p + L }; p < end; p += sizeof(rgen)) {
const auto x {rgen() };
std::copy_n(reinterpret_cast<const char*>(&x), sizeof(rgen), p);
}
break;
case OPTB:
std::cout << "Option B\n";
for (size_t i {}; i < L; ++i)
s[i] = 'a' + (rgen() % ('z' - 'a' + 1));
break;
case OPTC:
std::cout << "Option C\n";
std::fill_n(s.get(), L * sizeof(char), 'a');
for (size_t i {}; i < L / 1024; ++i)
s[rgen() % (L - 1)] = 'a' + (rgen() % ('z' - 'a' + 1));
break;
default:
std::cout << "Unknown option\n";
}
std::vector<const char*> vs(N);
if (L) {
s[L - 1] = 0;
for (size_t i {}; i < N; ++i)
vs[i] = &s[rgen() % (L - 1)];
}
return vs;
}
int main() {
constexpr Opts opt { OPTA };
const auto [L, N] {setOpt(opt)};
const auto s { std::make_unique<char[]>(L) };
const auto t0 { std::chrono::system_clock::now() };
auto vs { init(opt, s, L, N) };
const auto t1 { std::chrono::system_clock::now() };
std::cout << "Prep time(L=" << L << ", N=" << N << "): " << duration_cast<std::chrono::milliseconds>(t1 - t0).count() << "ms" << '\n';
size_t count {};
std::sort(vs.begin(), vs.end(), [&](const char* a, const char* b) { ++count; return compare1(a, b, 1); });
const auto t2 { std::chrono::system_clock::now() };
std::cout << "Sort time: " << duration_cast<std::chrono::milliseconds>(t2 - t1).count() << "ms (" << count << " comparisons)" << '\n';
size_t count1 {};
std::sort(vs.begin(), vs.end(), [&](const char* a, const char* b) { ++count1; return compare2(a, b, 1); });
const auto t3 { std::chrono::system_clock::now() };
std::cout << "Second sort time: " << std::chrono::duration_cast<std::chrono::milliseconds>(t3 - t2).count() << "ms (" << count1 << " comparisons)" << '\n';
}
| |