// WETSort.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include "../arkiny/dclb/Sort.h" #include "../ccm9026/JFSort/JFSort.h" #include "../djarksnd/sort.h" #include "../insun/Sort/Sort/SquickSort.h" #define partition es_partition #include "../prauser/ESSort.h" #undef partition #include "../witdrg/wc.h" #include #include #include #include #include #include std::string sha1(const void* p, size_t s); const size_t testLength[] = { 1ULL << 21, 1ULL << 27, #ifndef _DEBUG 1ULL << 31, 1ULL << 33 #endif }; enum TestUnitId { stl = -1, arkiny = 0, ccm9026, djarksnd, insun, prauser, witdrg, MAX_UID }; const char* uidString[MAX_UID] = { "arkiny", "ccm9026", "djarksnd", "insun", "prauser", "witdrg" }; struct TestScore { bool error; double sum; int num; }; TestScore testScore[MAX_UID] = { 0 }; struct TestResult { double t; std::string hash; }; #pragma pack(push, 1) template struct Element { int8_t buffer[s]; bool operator < (const Element& other) const { const int8_t* p0 = buffer; const int8_t* p1 = other.buffer; for (size_t i = 0; i < s; ++i) { int n = p0[0] - p1[0]; if (n) return n > 0; p0++; p1++; } return false; } }; #pragma pack(pop) static std::vector data0, data1; template TestResult TestUnit(int index) { std::function fn; switch (index) { case stl: fn = [](ElementType* items, size_t numItems) { std::sort(&items[0], &items[numItems], std::less()); }; break; case arkiny: fn = [](ElementType* items, size_t numItems) { dc::sort(&items[0], &items[numItems], std::less()); }; break; case ccm9026: fn = [](ElementType* items, size_t numItems) { JFFoundation::JFAlgorithm::_Sort(&items[0], &items[numItems], std::less()); }; break; case djarksnd: fn = [](ElementType* items, size_t numItems) { sort::sort(&items[0], &items[numItems], std::less()); }; break; case insun: fn = [](ElementType* items, size_t numItems) { // ERROR //SunSort::SSort(items, &items[0], &items[numItems - 1], std::less()); }; break; case prauser: fn = [](ElementType* items, size_t numItems) { // ERROR //std::less tmp; //ES::quickSort>(&items[0], &items[numItems], tmp); }; break; case witdrg: fn = [](ElementType* items, size_t numItems) { // ERROR //wc::sort(&items[0], &items[numItems], std::less()); }; break; } if (fn) { std::chrono::high_resolution_clock clock; using sec = std::chrono::duration>; data1.resize(data0.size()); memcpy(data1.data(), data0.data(), data0.size()); size_t s = sizeof(ElementType); size_t numItems = data1.size() / s; auto start = clock.now(); fn(reinterpret_cast(data1.data()), numItems); auto end = clock.now(); TestResult res; res.t = std::chrono::duration_cast(end - start).count(); res.hash = sha1(data1.data(), data1.size()).c_str(); return res; } throw std::runtime_error("unexpected error!"); } template void DoSortTest(void) { size_t numItems = data0.size() / unitSize; TestResult base = TestUnit>(stl); printf("[%s] items: %zu / %zu, elapsed: %f, hash: %s\n", "STD", unitSize, numItems, base.t, base.hash.c_str()); for (int i = 0; i < MAX_UID; ++i) { TestScore& score = testScore[i]; if (!score.error) { //printf("[%s] sorting...\n", uidString[i]); TestResult r = TestUnit>(i); if (base.hash == r.hash) { double s = base.t / r.t; score.sum += s; score.num++; printf("[%s] items: %zu, elapsed: %f, score:%d\n", uidString[i], numItems, r.t, int(s * 100)); } else { printf("[%s] error!! [REJECTED]\n", uidString[i]); score.error = true; } } } } void RunTest(size_t size) { std::random_device rdev; std::default_random_engine re(rdev()); std::uniform_int_distribution dist(0, 0xff); if (1) { size_t s = 64; while (s < size) s <<= 1; size = s; } // generate random number. data0.clear(); data0.resize(size); int16_t tmp = 0; printf("Generating random data... (%zu bytes)\n", size); for (size_t i = 0, e = size / sizeof(int32_t); i < e; ++i) { int16_t x = dist(re); int16_t y = (i ^ (tmp << 4)) & 0xff; tmp = y; reinterpret_cast(data0.data())[i] = (x << 16) | y; } // 3 bytes DoSortTest<3>(); // 4 bytes DoSortTest<4>(); // 5 bytes DoSortTest<5>(); // 9 bytes DoSortTest<9>(); // 16 bytes DoSortTest<16>(); // 17 bytes DoSortTest<17>(); // 64 DoSortTest<64>(); // 97 bytes DoSortTest<97>(); // 128 DoSortTest<128>(); // 512 DoSortTest<512>(); // 1024 DoSortTest<1024>(); // 4096 DoSortTest<4096>(); } int main() { // Set .error to 'true' to run the test! testScore[arkiny].error = true; testScore[ccm9026].error = true; testScore[djarksnd].error = true; testScore[insun].error = true; testScore[prauser].error = true; testScore[witdrg].error = true; auto PrintScore = [](int phase) { printf("------------ SCORE (%d/%d) --------------\n", phase, int(std::size(testLength))); for (int i = 0; i < MAX_UID; ++i) { const TestScore& score = testScore[i]; if (score.error) { printf("UID(%s) rejected. (ERROR)\n", uidString[i]); } else { uint32_t s = (score.sum / double(score.num)) * 100.0; printf("UID(%s) score: %d.\n", uidString[i], s); } } printf("-----------------------------------------\n\n"); }; int index = 1; for (size_t n : testLength) { printf("========= Phase %d / %d (%zu) ==========\n", index, int(std::size(testLength)), n); RunTest(n); PrintScore(index); index++; } }