Interstellar12312

std::sort versus Quicksort + Modified Insertion sort verses Quicksort + Standard Insertion Sort

Jul 21st, 2026
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.02 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <chrono>
  4. #include <random>
  5. #include <algorithm>
  6. #include <iomanip>
  7. #include <string>
  8.  
  9. // std::sort versus Quicksort + Modified Insertion sort verses Quicksort + Standard Insertion Sort
  10. // Tests RANDOM, REVERSE_SORTED, NEARLY_SORTED_ASC, NEARLY_SORTED_DESC, MANY_DUPLICATES, and ORGAN_PIPE
  11. // Switches to Insertion sort <= 32 elements
  12. // Contact Email [email protected]
  13. // Created by I.A
  14.  
  15. // Cache Clearing
  16. const size_t CACHE_SIZE_BYTES = 32 * 1024 * 1024;
  17. const size_t CACHE_SIZE_INTS = CACHE_SIZE_BYTES / sizeof(int);
  18. std::vector<int> cache_trasher(CACHE_SIZE_INTS, 0);
  19.  
  20. void flushCache() {
  21.     volatile int* p = cache_trasher.data();
  22.     for (size_t i = 0; i < CACHE_SIZE_INTS; i += 16) {
  23.         p[i] += 1;
  24.     }
  25. }
  26.  
  27. // ---------------------------------------------------------
  28. // Insertion Sorts
  29. // ---------------------------------------------------------
  30.  
  31. void standardInsertionSortSlice(std::vector<int>& arr, int low, int high) {
  32.     for (int i = low + 1; i <= high; i++) {
  33.         int key = arr[i];
  34.         int j = i - 1;
  35.         while (j >= low && arr[j] > key) {
  36.             arr[j + 1] = arr[j];
  37.             j--;
  38.         }
  39.         arr[j + 1] = key;
  40.     }
  41. }
  42.  
  43. void customJumpSortSlice(std::vector<int>& arr, int low, int high) {
  44.     for (int i = low + 1; i <= high; i++) {
  45.         int key = arr[i];
  46.         int j = i - 1;
  47.         while (j >= low && arr[j] > key) {
  48.             if (j >= low + 1) {
  49.                 arr[j + 1] = arr[j];
  50.                 if (arr[j - 1] > key) {
  51.                     arr[j] = arr[j - 1];
  52.                     j -= 2;
  53.                 } else {
  54.                     arr[j] = key;
  55.                     goto placed;
  56.                 }
  57.             } else {
  58.                 arr[j + 1] = arr[j];
  59.                 j--;
  60.             }
  61.         }
  62.         arr[j + 1] = key;
  63.         placed:;
  64.     }
  65. }
  66.  
  67. // ---------------------------------------------------------
  68. // Quicksort Core
  69. // ---------------------------------------------------------
  70.  
  71. int medianOfThree(std::vector<int>& arr, int low, int high) {
  72.     int mid = low + (high - low) / 2;
  73.     if (arr[mid] < arr[low]) std::swap(arr[low], arr[mid]);
  74.     if (arr[high] < arr[low]) std::swap(arr[low], arr[high]);
  75.     if (arr[mid] < arr[high]) std::swap(arr[mid], arr[high]);
  76.     return arr[high];
  77. }
  78.  
  79. int partition(std::vector<int>& arr, int low, int high) {
  80.     int pivot = medianOfThree(arr, low, high);
  81.     int i = low - 1;
  82.  
  83.     for (int j = low; j < high; j++) {
  84.         if (arr[j] <= pivot) {
  85.             i++;
  86.             std::swap(arr[i], arr[j]);
  87.         }
  88.     }
  89.     std::swap(arr[i + 1], arr[high]);
  90.     return i + 1;
  91. }
  92.  
  93. // ---------------------------------------------------------
  94. // Hybrid QuickSort Algorithms (Cutoff threshold: 32 elements)
  95. // ---------------------------------------------------------
  96.  
  97. void quickSortStandardInsertion(std::vector<int>& arr, int low, int high) {
  98.     if (low < high) {
  99.         if (high - low + 1 <= 32) {
  100.             standardInsertionSortSlice(arr, low, high);
  101.             return;
  102.         }
  103.         int pi = partition(arr, low, high);
  104.         quickSortStandardInsertion(arr, low, pi - 1);
  105.         quickSortStandardInsertion(arr, pi + 1, high);
  106.     }
  107. }
  108.  
  109. void quickSortCustomJump(std::vector<int>& arr, int low, int high) {
  110.     if (low < high) {
  111.         if (high - low + 1 <= 32) {
  112.             customJumpSortSlice(arr, low, high);
  113.             return;
  114.         }
  115.         int pi = partition(arr, low, high);
  116.         quickSortCustomJump(arr, low, pi - 1);
  117.         quickSortCustomJump(arr, pi + 1, high);
  118.     }
  119. }
  120.  
  121. // ---------------------------------------------------------
  122. // Data Generation Suite
  123. // ---------------------------------------------------------
  124.  
  125. enum class DataType {
  126.     RANDOM,
  127.     REVERSE_SORTED,
  128.     NEARLY_SORTED_ASC,
  129.     NEARLY_SORTED_DESC,
  130.     MANY_DUPLICATES,
  131.     ORGAN_PIPE
  132. };
  133.  
  134. std::string getDataTypeName(DataType type) {
  135.     switch (type) {
  136.         case DataType::RANDOM: return "Random";
  137.         case DataType::REVERSE_SORTED: return "Reverse Sorted";
  138.         case DataType::NEARLY_SORTED_ASC: return "Nearly Sorted (Asc)";
  139.         case DataType::NEARLY_SORTED_DESC: return "Nearly Sorted (Desc)";
  140.         case DataType::MANY_DUPLICATES: return "Many Duplicates";
  141.         case DataType::ORGAN_PIPE: return "Organ Pipe";
  142.         default: return "Unknown";
  143.     }
  144. }
  145.  
  146. std::vector<int> generateData(DataType type, int size, std::mt19937& gen) {
  147.     std::vector<int> arr(size);
  148.     switch (type) {
  149.         case DataType::RANDOM: {
  150.             std::uniform_int_distribution<> dist(1, size * 10);
  151.             for (int& x : arr) x = dist(gen);
  152.             break;
  153.         }
  154.         case DataType::REVERSE_SORTED: {
  155.             for (int i = 0; i < size; ++i) arr[i] = size - i;
  156.             break;
  157.         }
  158.         case DataType::NEARLY_SORTED_ASC: {
  159.             for (int i = 0; i < size; ++i) arr[i] = i;
  160.             std::uniform_int_distribution<> dist(0, size - 1);
  161.             // 5% noise factor
  162.             for (int i = 0; i < size / 20; ++i) std::swap(arr[dist(gen)], arr[dist(gen)]);
  163.             break;
  164.         }
  165.         case DataType::NEARLY_SORTED_DESC: {
  166.             for (int i = 0; i < size; ++i) arr[i] = size - i;
  167.             std::uniform_int_distribution<> dist(0, size - 1);
  168.             // 5% noise factor
  169.             for (int i = 0; i < size / 20; ++i) std::swap(arr[dist(gen)], arr[dist(gen)]);
  170.             break;
  171.         }
  172.         case DataType::MANY_DUPLICATES: {
  173.             std::uniform_int_distribution<> dist(1, 10); // Only 10 distinct values
  174.             for (int& x : arr) x = dist(gen);
  175.             break;
  176.         }
  177.         case DataType::ORGAN_PIPE: {
  178.             for (int i = 0; i < size / 2; ++i) arr[i] = i;
  179.             for (int i = size / 2; i < size; ++i) arr[i] = size - i;
  180.             break;
  181.         }
  182.     }
  183.     return arr;
  184. }
  185.  
  186. // ---------------------------------------------------------
  187. // Main Benchmark
  188. // ---------------------------------------------------------
  189.  
  190. int main() {
  191.     const int NUM_ELEMENTS = 10000;
  192.     const int NUM_TRIALS = 1000;
  193.  
  194.     std::random_device rd;
  195.     std::mt19937 gen(rd());
  196.  
  197.     DataType types[] = {
  198.         DataType::RANDOM, DataType::REVERSE_SORTED, DataType::NEARLY_SORTED_ASC,
  199.         DataType::NEARLY_SORTED_DESC, DataType::MANY_DUPLICATES,
  200.         DataType::ORGAN_PIPE
  201.     };
  202.  
  203.     std::cout << "Starting benchmark suite (Array Size: " << NUM_ELEMENTS
  204.               << ", Trials per pattern: " << NUM_TRIALS << ")\n";
  205.     std::cout << std::string(105, '=') << std::endl;
  206.     std::cout << std::left << std::setw(25) << "Data Pattern"
  207.               << std::setw(25) << "| std::sort (s)"
  208.               << std::setw(30) << "| Quick + Std Insert (s)"
  209.               << std::setw(25) << "| Quick + Custom Jump (s)" << std::endl;
  210.     std::cout << std::string(105, '-') << std::endl;
  211.  
  212.     for (DataType type : types) {
  213.         double totalStdSort = 0, totalQuickStd = 0, totalQuickJump = 0;
  214.  
  215.         for (int t = 0; t < NUM_TRIALS; ++t) {
  216.             std::vector<int> data1 = generateData(type, NUM_ELEMENTS, gen);
  217.             std::vector<int> data2 = data1;
  218.             std::vector<int> data3 = data1;
  219.  
  220.             // 1. Benchmark std::sort
  221.             auto s3 = std::chrono::steady_clock::now();
  222.             std::sort(data3.begin(), data3.end());
  223.             auto e3 = std::chrono::steady_clock::now();
  224.             totalStdSort += std::chrono::duration<double>(e3 - s3).count();
  225.  
  226.             // 2. Benchmark QuickSort + Standard Insertion
  227.             auto s1 = std::chrono::steady_clock::now();
  228.             quickSortStandardInsertion(data1, 0, NUM_ELEMENTS - 1);
  229.             auto e1 = std::chrono::steady_clock::now();
  230.             totalQuickStd += std::chrono::duration<double>(e1 - s1).count();
  231.  
  232.             // 3. Benchmark QuickSort + Custom Jump Sort
  233.             auto s2 = std::chrono::steady_clock::now();
  234.             quickSortCustomJump(data2, 0, NUM_ELEMENTS - 1);
  235.             auto e2 = std::chrono::steady_clock::now();
  236.             totalQuickJump += std::chrono::duration<double>(e2 - s2).count();
  237.  
  238.             // Verify Logic
  239.             if (!std::is_sorted(data1.begin(), data1.end()) ||
  240.                 !std::is_sorted(data2.begin(), data2.end()) ||
  241.                 !std::is_sorted(data3.begin(), data3.end())) {
  242.                 std::cout << "CRITICAL ERROR: Array sorting failed on pattern: "
  243.                           << getDataTypeName(type) << std::endl;
  244.                 return 1;
  245.             }
  246.         }
  247.  
  248.         // Print results for this data type
  249.         std::cout << std::left << std::setw(25) << getDataTypeName(type)
  250.                   << "| " << std::setw(23) << std::fixed << std::setprecision(6) << totalStdSort
  251.                   << "| " << std::setw(28) << std::fixed << std::setprecision(6) << totalQuickStd
  252.                   << "| " << std::setw(23) << std::fixed << std::setprecision(6) << totalQuickJump
  253.                   << std::endl;
  254.     }
  255.  
  256.     std::cout << std::string(105, '=') << std::endl;
  257.     return 0;
  258. }
Advertisement
Add Comment
Please, Sign In to add comment