Main.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #include <chrono>
  2. #include <iostream>
  3. long getNanos()
  4. {
  5. return std::chrono::high_resolution_clock::now().time_since_epoch().count();
  6. }
  7. int intKey(const int &i) { return i; }
  8. static unsigned long seed = 0;
  9. int randomInt()
  10. {
  11. seed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFF;
  12. return static_cast<int>(seed >> 17);
  13. }
  14. template <typename T> T *mergeSort(const T *in, int size, int (*key)(const T &))
  15. {
  16. T *out = new T[size];
  17. for (int i = 0; i < size; ++i)
  18. {
  19. out[i] = in[i];
  20. }
  21. if (size <= 1)
  22. {
  23. return out;
  24. }
  25. // split
  26. int sizeLeft = size / 2;
  27. int sizeRight = (size + 1) / 2;
  28. T *left = out;
  29. T *right = out + sizeLeft;
  30. left = mergeSort(left, sizeLeft, key);
  31. right = mergeSort(right, sizeRight, key);
  32. // merge
  33. int rightCounter = 0;
  34. int leftCounter = 0;
  35. for (int i = 0; i < size; ++i)
  36. {
  37. if (leftCounter >= sizeLeft)
  38. {
  39. out[i] = right[rightCounter];
  40. ++rightCounter;
  41. }
  42. else if (rightCounter >= sizeRight)
  43. {
  44. out[i] = left[leftCounter];
  45. ++leftCounter;
  46. }
  47. else if (key(left[leftCounter]) < key(right[rightCounter]))
  48. {
  49. out[i] = left[leftCounter];
  50. ++leftCounter;
  51. }
  52. else
  53. {
  54. out[i] = right[rightCounter];
  55. ++rightCounter;
  56. }
  57. }
  58. delete[] right;
  59. delete[] left;
  60. return out;
  61. }
  62. void cacheTest()
  63. {
  64. for (int size = 512; size < 100'000'000; size *= 2)
  65. {
  66. printf("Cache Test with size = %9d | ", size);
  67. constexpr int max = 500;
  68. int *a = new int[size];
  69. seed = 0;
  70. for (int i = 0; i < size; i++)
  71. {
  72. a[i] = randomInt() % max;
  73. }
  74. long time = -getNanos();
  75. int *b = mergeSort(a, size, intKey);
  76. time += getNanos();
  77. printf("%10ld ns | %7.2lf ns / entry \n", time,
  78. (static_cast<double>(time) / size));
  79. delete[] a;
  80. delete[] b;
  81. }
  82. }
  83. struct A
  84. {
  85. int key;
  86. char filler[32];
  87. };
  88. int aKey(const A &a) { return a.key; }
  89. void structTest()
  90. {
  91. for (int size = 512; size < 100'000'000; size *= 2)
  92. {
  93. printf("Struct Test with size = %9d | ", size);
  94. constexpr int max = 500;
  95. A *a = new A[size];
  96. seed = 0;
  97. for (int i = 0; i < size; i++)
  98. {
  99. a[i].key = randomInt() % max;
  100. }
  101. long time = -getNanos();
  102. A *b = mergeSort(a, size, aKey);
  103. time += getNanos();
  104. printf("%10ld ns | %7.2lf ns / entry \n", time,
  105. (static_cast<double>(time) / size));
  106. delete[] a;
  107. delete[] b;
  108. }
  109. }
  110. int pointerKey(int *const &a) { return *a; }
  111. void pointerTest()
  112. {
  113. for (int size = 512; size < 100'000'000; size *= 2)
  114. {
  115. printf("Pointer Test with size = %9d | ", size);
  116. constexpr int max = 500;
  117. int **a = new int *[size];
  118. seed = 0;
  119. for (int i = 0; i < size; i++)
  120. {
  121. a[i] = new int(randomInt() % max);
  122. }
  123. long time = -getNanos();
  124. int **b = mergeSort<int *>(a, size, pointerKey);
  125. time += getNanos();
  126. printf("%10ld ns | %7.2lf ns / entry \n", time,
  127. (static_cast<double>(time) / size));
  128. for (int i = 0; i < size; i++)
  129. {
  130. delete a[i];
  131. }
  132. delete[] a;
  133. delete[] b;
  134. }
  135. }
  136. int main()
  137. {
  138. cacheTest();
  139. structTest();
  140. pointerTest();
  141. return 0;
  142. }