fork(1) download
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <chrono>
  4.  
  5. // We are now sorting 100,000 elements at compile time!
  6. const std::size_t SIZE = 100000;
  7.  
  8. // =====================================================================
  9. // 1. C++14 Constexpr Array
  10. // =====================================================================
  11. template <typename T, std::size_t N>
  12. struct CXArray {
  13. T data[N];
  14. constexpr T& operator[](std::size_t i) { return data[i]; }
  15. constexpr const T& operator[](std::size_t i) const { return data[i]; }
  16. constexpr T* begin() { return data; }
  17. constexpr T* end() { return data + N; }
  18. constexpr const T* begin() const { return data; }
  19. constexpr const T* end() const { return data + N; }
  20. };
  21.  
  22. // =====================================================================
  23. // 2. The 100k Strategy: Constexpr Radix Sort O(N)
  24. // Reduces 20,000,000 compiler steps to just 1,600,000 steps
  25. // =====================================================================
  26. template <typename T, std::size_t N>
  27. constexpr CXArray<T, N> generate_radix_sort(CXArray<T, N> arr) {
  28. // We allocate a buffer entirely inside compiler memory
  29. CXArray<T, N> buffer{};
  30.  
  31. // 4 passes for 32-bit integers (8 bits / base-256 per pass)
  32. for (int byte = 0; byte < 4; ++byte) {
  33. int counts[256] = {0};
  34. int shift = byte * 8;
  35.  
  36. // Step A: Count frequencies (O(N))
  37. for (std::size_t i = 0; i < N; ++i) {
  38. unsigned int val = static_cast<unsigned int>(arr[i]);
  39. counts[(val >> shift) & 0xFF]++;
  40. }
  41.  
  42. // Step B: Prefix sums (O(256))
  43. int pos[256] = {0};
  44. for (int i = 1; i < 256; ++i) {
  45. pos[i] = pos[i - 1] + counts[i - 1];
  46. }
  47.  
  48. // Step C: Scatter to buffer (O(N))
  49. for (std::size_t i = 0; i < N; ++i) {
  50. unsigned int val = static_cast<unsigned int>(arr[i]);
  51. int bucket = (val >> shift) & 0xFF;
  52. buffer[pos[bucket]++] = arr[i];
  53. }
  54.  
  55. // Step D: Copy back to array (O(N))
  56. for (std::size_t i = 0; i < N; ++i) {
  57. arr[i] = buffer[i];
  58. }
  59. }
  60.  
  61. return arr;
  62. }
  63.  
  64. // =====================================================================
  65. // 3. Constexpr Data Generation
  66. // =====================================================================
  67. constexpr CXArray<int, SIZE> generate_random_data() {
  68. CXArray<int, SIZE> arr{};
  69. unsigned int seed = 987654321;
  70. for (std::size_t i = 0; i < SIZE; ++i) {
  71. seed = (1103515245 * seed + 12345) % 2147483648;
  72. arr[i] = seed % 10000000; // Generate numbers up to 10 million
  73. }
  74. return arr;
  75. }
  76.  
  77. // 💥 COMPILER EXECUTES 100,000 ELEMENT RADIX SORT HERE 💥
  78. constexpr auto unsorted_data = generate_random_data();
  79. constexpr auto sorted_data = generate_radix_sort(unsorted_data);
  80.  
  81. // =====================================================================
  82. // Benchmark Engine
  83. // =====================================================================
  84. int main() {
  85. std::cout << "Data Size: " << SIZE << " elements\n";
  86.  
  87. // 1. Runtime Standard Sort Benchmark
  88. CXArray<int, SIZE> runtime_data = unsorted_data;
  89.  
  90. auto start1 = std::chrono::high_resolution_clock::now();
  91. std::sort(runtime_data.begin(), runtime_data.end());
  92. auto end1 = std::chrono::high_resolution_clock::now();
  93. std::chrono::duration<double, std::milli> time_std = end1 - start1;
  94.  
  95. // 2. Compile-Time Sort Benchmark (0ms)
  96. auto start2 = std::chrono::high_resolution_clock::now();
  97. volatile int dummy = sorted_data[0];
  98. auto end2 = std::chrono::high_resolution_clock::now();
  99. std::chrono::duration<double, std::milli> time_cx = end2 - start2;
  100.  
  101. std::cout << "\n--- Benchmark Results ---\n";
  102. std::cout << "Runtime std::sort: " << time_std.count() << " ms\n";
  103. std::cout << "Compile-Time Radix Sort: " << time_cx.count() << " ms\n";
  104.  
  105. bool correct = std::is_sorted(sorted_data.begin(), sorted_data.end());
  106. std::cout << "\nCompile-Time array is sorted correctly: " << (correct ? "True" : "False") << "\n";
  107.  
  108. return 0;
  109. }
Success #stdin #stdout 0.01s 5240KB
stdin
Standard input is empty
stdout
Data Size: 100000 elements

--- Benchmark Results ---
Runtime std::sort:          6.02737 ms
Compile-Time Radix Sort:    4.6e-05 ms

Compile-Time array is sorted correctly: True