W_Engine_Team_Study

WETSort.cpp 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // WETSort.cpp : This file contains the 'main' function. Program execution begins and ends there.
  2. //
  3. #include "../arkiny/dclb/Sort.h"
  4. #include "../ccm9026/JFSort/JFSort.h"
  5. #include "../djarksnd/sort.h"
  6. #include "../insun/Sort/Sort/SquickSort.h"
  7. #define partition es_partition
  8. #include "../prauser/ESSort.h"
  9. #undef partition
  10. #include "../witdrg/wc.h"
  11. #include <random>
  12. #include <chrono>
  13. #include <ratio>
  14. #include <algorithm>
  15. #include <vector>
  16. #include <functional>
  17. std::string sha1(const void* p, size_t s);
  18. const size_t testLength[] = {
  19. 1ULL << 21,
  20. 1ULL << 27,
  21. #ifndef _DEBUG
  22. 1ULL << 31,
  23. 1ULL << 33
  24. #endif
  25. };
  26. enum TestUnitId
  27. {
  28. stl = -1,
  29. arkiny = 0,
  30. ccm9026,
  31. djarksnd,
  32. insun,
  33. prauser,
  34. witdrg,
  35. MAX_UID
  36. };
  37. const char* uidString[MAX_UID] = {
  38. "arkiny",
  39. "ccm9026",
  40. "djarksnd",
  41. "insun",
  42. "prauser",
  43. "witdrg"
  44. };
  45. struct TestScore
  46. {
  47. bool error;
  48. double sum;
  49. int num;
  50. };
  51. TestScore testScore[MAX_UID] = { 0 };
  52. struct TestResult
  53. {
  54. double t;
  55. std::string hash;
  56. };
  57. #pragma pack(push, 1)
  58. template <size_t s>
  59. struct Element
  60. {
  61. int8_t buffer[s];
  62. bool operator < (const Element& other) const
  63. {
  64. const int8_t* p0 = buffer;
  65. const int8_t* p1 = other.buffer;
  66. for (size_t i = 0; i < s; ++i)
  67. {
  68. int n = p0[0] - p1[0];
  69. if (n)
  70. return n > 0;
  71. p0++;
  72. p1++;
  73. }
  74. return false;
  75. }
  76. };
  77. #pragma pack(pop)
  78. static std::vector<uint8_t> data0, data1;
  79. template <typename ElementType>
  80. TestResult TestUnit(int index)
  81. {
  82. std::function<void(ElementType*, size_t)> fn;
  83. switch (index)
  84. {
  85. case stl:
  86. fn = [](ElementType* items, size_t numItems)
  87. {
  88. std::sort(&items[0], &items[numItems], std::less<ElementType>());
  89. };
  90. break;
  91. case arkiny:
  92. fn = [](ElementType* items, size_t numItems)
  93. {
  94. dc::sort(&items[0], &items[numItems], std::less<ElementType>());
  95. };
  96. break;
  97. case ccm9026:
  98. fn = [](ElementType* items, size_t numItems)
  99. {
  100. JFFoundation::JFAlgorithm::_Sort(&items[0], &items[numItems], std::less<ElementType>());
  101. };
  102. break;
  103. case djarksnd:
  104. fn = [](ElementType* items, size_t numItems)
  105. {
  106. sort::sort(&items[0], &items[numItems], std::less<ElementType>());
  107. };
  108. break;
  109. case insun:
  110. fn = [](ElementType* items, size_t numItems)
  111. {
  112. // ERROR
  113. //SunSort::SSort(items, &items[0], &items[numItems - 1], std::less<ElementType>());
  114. };
  115. break;
  116. case prauser:
  117. fn = [](ElementType* items, size_t numItems)
  118. {
  119. // ERROR
  120. //std::less<ElementType> tmp;
  121. //ES::quickSort<ElementType*, std::less<ElementType>>(&items[0], &items[numItems], tmp);
  122. };
  123. break;
  124. case witdrg:
  125. fn = [](ElementType* items, size_t numItems)
  126. {
  127. // ERROR
  128. //wc::sort(&items[0], &items[numItems], std::less<ElementType>());
  129. };
  130. break;
  131. }
  132. if (fn)
  133. {
  134. std::chrono::high_resolution_clock clock;
  135. using sec = std::chrono::duration<double, std::ratio<1, 1>>;
  136. data1.resize(data0.size());
  137. memcpy(data1.data(), data0.data(), data0.size());
  138. size_t s = sizeof(ElementType);
  139. size_t numItems = data1.size() / s;
  140. auto start = clock.now();
  141. fn(reinterpret_cast<ElementType*>(data1.data()), numItems);
  142. auto end = clock.now();
  143. TestResult res;
  144. res.t = std::chrono::duration_cast<sec>(end - start).count();
  145. res.hash = sha1(data1.data(), data1.size()).c_str();
  146. return res;
  147. }
  148. throw std::runtime_error("unexpected error!");
  149. }
  150. template <size_t unitSize>
  151. void DoSortTest(void)
  152. {
  153. size_t numItems = data0.size() / unitSize;
  154. TestResult base = TestUnit<Element<unitSize>>(stl);
  155. printf("[%s] items: %zu / %zu, elapsed: %f, hash: %s\n", "STD", unitSize, numItems, base.t, base.hash.c_str());
  156. for (int i = 0; i < MAX_UID; ++i)
  157. {
  158. TestScore& score = testScore[i];
  159. if (!score.error)
  160. {
  161. //printf("[%s] sorting...\n", uidString[i]);
  162. TestResult r = TestUnit<Element<unitSize>>(i);
  163. if (base.hash == r.hash)
  164. {
  165. double s = base.t / r.t;
  166. score.sum += s;
  167. score.num++;
  168. printf("[%s] items: %zu, elapsed: %f, score:%d\n", uidString[i], numItems, r.t, int(s * 100));
  169. }
  170. else
  171. {
  172. printf("[%s] error!! [REJECTED]\n", uidString[i]);
  173. score.error = true;
  174. }
  175. }
  176. }
  177. }
  178. void RunTest(size_t size)
  179. {
  180. std::random_device rdev;
  181. std::default_random_engine re(rdev());
  182. std::uniform_int_distribution<unsigned short> dist(0, 0xff);
  183. if (1)
  184. {
  185. size_t s = 64;
  186. while (s < size)
  187. s <<= 1;
  188. size = s;
  189. }
  190. // generate random number.
  191. data0.clear();
  192. data0.resize(size);
  193. int16_t tmp = 0;
  194. printf("Generating random data... (%zu bytes)\n", size);
  195. for (size_t i = 0, e = size / sizeof(int32_t); i < e; ++i)
  196. {
  197. int16_t x = dist(re);
  198. int16_t y = (i ^ (tmp << 4)) & 0xff;
  199. tmp = y;
  200. reinterpret_cast<int16_t*>(data0.data())[i] = (x << 16) | y;
  201. }
  202. // 3 bytes
  203. DoSortTest<3>();
  204. // 4 bytes
  205. DoSortTest<4>();
  206. // 5 bytes
  207. DoSortTest<5>();
  208. // 9 bytes
  209. DoSortTest<9>();
  210. // 16 bytes
  211. DoSortTest<16>();
  212. // 17 bytes
  213. DoSortTest<17>();
  214. // 64
  215. DoSortTest<64>();
  216. // 97 bytes
  217. DoSortTest<97>();
  218. // 128
  219. DoSortTest<128>();
  220. // 512
  221. DoSortTest<512>();
  222. // 1024
  223. DoSortTest<1024>();
  224. // 4096
  225. DoSortTest<4096>();
  226. }
  227. int main()
  228. {
  229. // Set .error to 'true' to run the test!
  230. testScore[arkiny].error = true;
  231. testScore[ccm9026].error = true;
  232. testScore[djarksnd].error = true;
  233. testScore[insun].error = true;
  234. testScore[prauser].error = true;
  235. testScore[witdrg].error = true;
  236. auto PrintScore = [](int phase)
  237. {
  238. printf("------------ SCORE (%d/%d) --------------\n", phase, int(std::size(testLength)));
  239. for (int i = 0; i < MAX_UID; ++i)
  240. {
  241. const TestScore& score = testScore[i];
  242. if (score.error)
  243. {
  244. printf("UID(%s) rejected. (ERROR)\n", uidString[i]);
  245. }
  246. else
  247. {
  248. uint32_t s = (score.sum / double(score.num)) * 100.0;
  249. printf("UID(%s) score: %d.\n", uidString[i], s);
  250. }
  251. }
  252. printf("-----------------------------------------\n\n");
  253. };
  254. int index = 1;
  255. for (size_t n : testLength)
  256. {
  257. printf("========= Phase %d / %d (%zu) ==========\n", index, int(std::size(testLength)), n);
  258. RunTest(n);
  259. PrintScore(index);
  260. index++;
  261. }
  262. }