W_Engine_Team_Study

WETSort.cpp 8.3KB

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