W_Engine_Team_Study

WETSort.cpp 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  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. #ifdef _DEBUG
  20. 1ULL << 21,
  21. 1ULL << 24,
  22. 1ULL << 29,
  23. #else
  24. 1ULL << 31,
  25. 1ULL << 32,
  26. 1ULL << 33
  27. #endif
  28. };
  29. enum TestUnitId
  30. {
  31. stl = -1,
  32. arkiny = 0,
  33. ccm9026,
  34. djarksnd,
  35. insun,
  36. prauser,
  37. witdrg,
  38. MAX_UID
  39. };
  40. const char* uidString[MAX_UID] = {
  41. "arkiny",
  42. "ccm9026",
  43. "djarksnd",
  44. "insun",
  45. "prauser",
  46. "witdrg"
  47. };
  48. struct TestScore
  49. {
  50. bool error;
  51. double sum;
  52. int num;
  53. };
  54. TestScore testScore[MAX_UID] = { 0 };
  55. struct TestResult
  56. {
  57. double t;
  58. std::string hash;
  59. };
  60. enum GenerateDataTypes
  61. {
  62. GenUniform32,
  63. GenUniform16,
  64. GenUniform16Xor,
  65. GenUniform8,
  66. GenUniform8Xor,
  67. GenNormal64,
  68. GenNormal32,
  69. };
  70. #pragma pack(push, 1)
  71. template <size_t s>
  72. struct Element
  73. {
  74. int8_t buffer[s];
  75. bool operator < (const Element& other) const
  76. {
  77. for (size_t i = 0; i < s; ++i)
  78. {
  79. int n = int(buffer[i]) - int(other.buffer[i]);
  80. if (n)
  81. return n > 0;
  82. }
  83. return false;
  84. }
  85. };
  86. #pragma pack(pop)
  87. static std::vector<uint8_t> data0, data1;
  88. template <typename ElementType>
  89. TestResult TestUnit(int index)
  90. {
  91. std::function<void(ElementType*, size_t)> fn;
  92. switch (index)
  93. {
  94. case stl:
  95. fn = [](ElementType* items, size_t numItems)
  96. {
  97. std::sort(&items[0], &items[numItems], std::less<ElementType>());
  98. };
  99. break;
  100. case arkiny:
  101. fn = [](ElementType* items, size_t numItems)
  102. {
  103. dc::sort(&items[0], &items[numItems], std::less<ElementType>());
  104. };
  105. break;
  106. case ccm9026:
  107. fn = [](ElementType* items, size_t numItems)
  108. {
  109. JFFoundation::JFAlgorithm::_Sort(&items[0], &items[numItems], std::less<ElementType>());
  110. };
  111. break;
  112. case djarksnd:
  113. fn = [](ElementType* items, size_t numItems)
  114. {
  115. sort::sort(&items[0], &items[numItems], std::less<ElementType>());
  116. };
  117. break;
  118. case insun:
  119. fn = [](ElementType* items, size_t numItems)
  120. {
  121. // ERROR
  122. //SunSort::SSort(items, &items[0], &items[numItems - 1], std::less<ElementType>());
  123. };
  124. break;
  125. case prauser:
  126. fn = [](ElementType* items, size_t numItems)
  127. {
  128. // ERROR
  129. //std::less<ElementType> tmp;
  130. //ES::quickSort<ElementType*, std::less<ElementType>>(&items[0], &items[numItems], tmp);
  131. };
  132. break;
  133. case witdrg:
  134. fn = [](ElementType* items, size_t numItems)
  135. {
  136. // ERROR
  137. //wc::sort(&items[0], &items[numItems], std::less<ElementType>());
  138. };
  139. break;
  140. }
  141. if (fn)
  142. {
  143. std::chrono::high_resolution_clock clock;
  144. using sec = std::chrono::duration<double, std::ratio<1, 1>>;
  145. data1.resize(data0.size());
  146. memcpy(data1.data(), data0.data(), data0.size());
  147. size_t s = sizeof(ElementType);
  148. size_t numItems = data1.size() / s;
  149. auto start = clock.now();
  150. fn(reinterpret_cast<ElementType*>(data1.data()), numItems);
  151. auto end = clock.now();
  152. TestResult res;
  153. res.t = std::chrono::duration_cast<sec>(end - start).count();
  154. res.hash = sha1(data1.data(), data1.size()).c_str();
  155. return res;
  156. }
  157. throw std::runtime_error("unexpected error!");
  158. }
  159. template <size_t unitSize>
  160. void DoSortTest(void)
  161. {
  162. size_t numItems = data0.size() / unitSize;
  163. TestResult base = TestUnit<Element<unitSize>>(stl);
  164. printf("[%s] items: %zu / %zu, elapsed: %f, hash: %s\n", "STD", unitSize, numItems, base.t, base.hash.c_str());
  165. for (int i = 0; i < MAX_UID; ++i)
  166. {
  167. TestScore& score = testScore[i];
  168. if (!score.error)
  169. {
  170. //printf("[%s] sorting...\n", uidString[i]);
  171. TestResult r = TestUnit<Element<unitSize>>(i);
  172. if (base.hash == r.hash)
  173. {
  174. double s = base.t / r.t;
  175. score.sum += s;
  176. score.num++;
  177. printf("[%s] items: %zu, elapsed: %f, score:%d\n", uidString[i], numItems, r.t, int(s * 100));
  178. }
  179. else
  180. {
  181. printf("[%s] error!! [REJECTED]\n", uidString[i]);
  182. score.error = true;
  183. }
  184. }
  185. }
  186. }
  187. void RunTest(size_t size, GenerateDataTypes type)
  188. {
  189. std::random_device rdev;
  190. std::default_random_engine re(rdev());
  191. if (1)
  192. {
  193. size_t s = 64;
  194. while (s < size)
  195. s <<= 1;
  196. size = s;
  197. }
  198. // generate random number.
  199. data0.clear();
  200. data0.resize(size);
  201. switch (type)
  202. {
  203. case GenUniform32:
  204. if (1)
  205. {
  206. printf("Generating random data... (%zu bytes, type: Uniform32)\n", size);
  207. std::uniform_int_distribution<uint32_t> dist(0, 0xffffffff);
  208. for (size_t i = 0, e = size / sizeof(uint32_t); i < e; ++i)
  209. {
  210. reinterpret_cast<uint32_t*>(data0.data())[i] = dist(re);
  211. }
  212. }
  213. break;
  214. case GenUniform16:
  215. if (1)
  216. {
  217. printf("Generating random data... (%zu bytes, type: Uniform16)\n", size);
  218. std::uniform_int_distribution<uint16_t> dist(0, 0xffff);
  219. for (size_t i = 0, e = size / sizeof(uint32_t); i < e; ++i)
  220. {
  221. reinterpret_cast<uint32_t*>(data0.data())[i] = dist(re);
  222. }
  223. }
  224. break;
  225. case GenUniform16Xor:
  226. if (1)
  227. {
  228. printf("Generating random data... (%zu bytes, type: Uniform16Xor)\n", size);
  229. std::uniform_int_distribution<uint16_t> dist(0, 0xffff);
  230. uint32_t tmp = dist(re);
  231. for (size_t i = 0, e = size / sizeof(uint32_t); i < e; ++i)
  232. {
  233. uint32_t x = dist(re);
  234. uint32_t y = (i ^ (tmp << 3)) & 0xff;
  235. tmp = y;
  236. reinterpret_cast<uint32_t*>(data0.data())[i] = (x << 16) | y;
  237. }
  238. }
  239. break;
  240. case GenUniform8:
  241. if (1)
  242. {
  243. printf("Generating random data... (%zu bytes, type: Uniform8)\n", size);
  244. std::uniform_int_distribution<uint16_t> dist(0, 0xff);
  245. for (size_t i = 0, e = size / sizeof(uint32_t); i < e; ++i)
  246. {
  247. reinterpret_cast<uint32_t*>(data0.data())[i] = dist(re);
  248. }
  249. }
  250. break;
  251. case GenUniform8Xor:
  252. if (1)
  253. {
  254. printf("Generating random data... (%zu bytes, type: Uniform8Xor)\n", size);
  255. std::uniform_int_distribution<uint16_t> dist(0, 0xff);
  256. uint32_t tmp = dist(re);
  257. for (size_t i = 0, e = size / sizeof(uint32_t); i < e; ++i)
  258. {
  259. uint32_t val = dist(re);
  260. val = val ^ (tmp << 1);
  261. tmp = val;
  262. reinterpret_cast<uint32_t*>(data0.data())[i] = val;
  263. }
  264. }
  265. break;
  266. case GenNormal64:
  267. if (1)
  268. {
  269. printf("Generating random data... (%zu bytes, type: Normal64)\n", size);
  270. std::normal_distribution<double> dist;
  271. for (size_t i = 0, e = size / sizeof(double); i < e; ++i)
  272. {
  273. reinterpret_cast<double*>(data0.data())[i] = dist(re);
  274. }
  275. }
  276. break;
  277. case GenNormal32:
  278. if (1)
  279. {
  280. printf("Generating random data... (%zu bytes, type: Normal32)\n", size);
  281. std::normal_distribution<float> dist;
  282. for (size_t i = 0, e = size / sizeof(float); i < e; ++i)
  283. {
  284. reinterpret_cast<float*>(data0.data())[i] = dist(re);
  285. }
  286. }
  287. break;
  288. }
  289. // 1 byte
  290. DoSortTest<1>();
  291. // 2 byte
  292. DoSortTest<2>();
  293. // 3 bytes
  294. DoSortTest<3>();
  295. // 4 bytes
  296. DoSortTest<4>();
  297. // 5 bytes
  298. DoSortTest<5>();
  299. // 6
  300. DoSortTest<6>();
  301. // 7
  302. DoSortTest<7>();
  303. // 9 bytes
  304. DoSortTest<9>();
  305. // 10
  306. DoSortTest<10>();
  307. // 11
  308. DoSortTest<11>();
  309. // 12
  310. DoSortTest<12>();
  311. // 13
  312. DoSortTest<13>();
  313. // 15
  314. DoSortTest<15>();
  315. // 17 bytes
  316. DoSortTest<17>();
  317. //// 32 bytes
  318. //DoSortTest<32>();
  319. //// 33 bytes
  320. //DoSortTest<33>();
  321. }
  322. int main()
  323. {
  324. // Set .error to '0' to run the test!
  325. testScore[arkiny].error = 1;
  326. testScore[ccm9026].error = 1;
  327. testScore[djarksnd].error = 1;
  328. testScore[insun].error = 1;
  329. testScore[prauser].error = 1;
  330. testScore[witdrg].error = 1;
  331. auto PrintScore = [](int phase)
  332. {
  333. printf("------------ SCORE (%d/%d) --------------\n", phase, int(std::size(testLength)));
  334. for (int i = 0; i < MAX_UID; ++i)
  335. {
  336. const TestScore& score = testScore[i];
  337. if (score.error)
  338. {
  339. printf("UID(%s) rejected. (ERROR)\n", uidString[i]);
  340. }
  341. else
  342. {
  343. uint32_t s = (score.sum / double(score.num)) * 100.0;
  344. const char* t = "";
  345. if (s > 100)
  346. t = "(PERFECT)";
  347. else if (s > 90)
  348. t = "(GOOD)";
  349. else if (s < 60)
  350. t = "(POOR)";
  351. printf("UID(%s) score: %d. %s\n", uidString[i], s, t);
  352. }
  353. }
  354. printf("-----------------------------------------\n\n");
  355. };
  356. int index = 1;
  357. for (size_t n : testLength)
  358. {
  359. printf("========= Phase %d / %d (%zu) ==========\n", index, int(std::size(testLength)), n);
  360. for (auto t : {
  361. GenUniform32,
  362. GenUniform16,
  363. GenUniform16Xor,
  364. GenUniform8,
  365. GenUniform8Xor,
  366. GenNormal64,
  367. GenNormal32
  368. })
  369. {
  370. RunTest(n, t);
  371. }
  372. //RunTest(n, GenNormal64);
  373. PrintScore(index);
  374. index++;
  375. }
  376. }