W_Engine_Team_Study

WETSort.cpp 9.1KB

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