Guest User

Test linear vs binary search speed

a guest
May 1st, 2026
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.65 KB | Cryptocurrency | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <time.h>
  5.  
  6. #define LIKELY(x)   __builtin_expect(!!(x), 1)
  7. #define UNLIKELY(x) __builtin_expect(!!(x), 0)
  8.  
  9. // Linear search function
  10. int linear_search(int arr[], int n, int target) {
  11.     for (int i = 0; i < n; i++) {
  12.         if (UNLIKELY(arr[i] == target))
  13.             return i;
  14.     }
  15.     return -1;
  16. }
  17.  
  18. int linear_search_no_branch(int arr[], int n, int target) {
  19.     int mask = -1;
  20.     for (int i = 0; i < n; i++) {
  21.         mask = (arr[i] == target) ? i : mask;
  22.     }
  23.     return mask;
  24. }
  25.  
  26. // Binary search function
  27. int binary_search(int arr[], int n, int target) {
  28.     int left = 0, right = n - 1;
  29.     while (left <= right) {
  30.         int mid = left + (right - left) / 2;
  31.         if (arr[mid] == target)
  32.             return mid;
  33.         else if (arr[mid] < target)
  34.             left = mid + 1;
  35.         else
  36.             right = mid - 1;
  37.     }
  38.     return -1;
  39. }
  40.  
  41. int binary_search_no_branch(int arr[], int n, int target) {
  42.     int left = 0, length = n - 1, result = -1;
  43.     while (length >= 1) {
  44.         int mid = left + length / 2;
  45.         result = (arr[mid] == target) ? mid : result;
  46.         left = (arr[mid] < target) ? mid + 1 : left;
  47.         length = length / 2;
  48.     }
  49.  
  50.     return arr[left] == target ? left : result;
  51. }
  52.  
  53. int binary_search_no_branch_depth(int arr[], int n, int target, int depth) {
  54.     int left = 0, right = n - 1, result = -1;
  55.     for (int i = 0; i < depth; i++) {
  56.         int mid = left + (right - left) / 2;
  57.         result = (arr[mid] == target) ? mid : result;
  58.         left = (arr[mid] < target) ? mid + 1 : left;
  59.         right = (arr[mid] > target) ? mid - 1 : right;
  60.     }
  61.     return result;
  62. }
  63.  
  64. int binary_search_no_branch_8(int arr[], int target) {
  65.     return binary_search_no_branch_depth(arr, 8, target, 4);
  66. }
  67.  
  68. int binary_search_no_branch_16(int arr[], int target) {
  69.     return binary_search_no_branch_depth(arr, 16, target, 5);
  70. }
  71.  
  72. // Struct for benchmark configuration
  73. typedef struct {
  74.     int array_size;
  75.     int repetitions;
  76.     bool last;
  77. } BenchmarkConfig;
  78.  
  79. // Benchmark function
  80. void benchmark_search(int size, int repetitions, bool last) {
  81.     int *arr = malloc(size * sizeof(int));
  82.     if (!arr) {
  83.         perror("Memory allocation failed");
  84.         return;
  85.     }
  86.  
  87.     // Seed random number generator
  88.     srand((unsigned int)time(NULL));
  89.  
  90.     // Fill array with ascending numbers
  91.     for (int i = 0; i < size; i++) {
  92.         arr[i] = i * 100 + rand() % 10;
  93.     }
  94.  
  95.     // Create array of targets to search
  96.     int *targets = malloc(repetitions * sizeof(int));
  97.     if (!targets) {
  98.         perror("Target array allocation failed");
  99.         free(arr);
  100.         return;
  101.     }
  102.  
  103.     for (int i = 0; i < repetitions; i++) {
  104.         targets[i] = last ? 1000000 + rand() % 1000 : arr[rand() % size];
  105.     }
  106.  
  107.     struct timespec start, end;
  108.     int r = 0;
  109.  
  110.     // Linear search benchmark
  111.     clock_gettime(CLOCK_MONOTONIC, &start);
  112.     if (size == 8) {
  113.         for (int i = 0; i < repetitions; i++) {
  114.             r += linear_search(arr, 8, targets[i]);
  115.         }
  116.     } else if (size == 16) {
  117.         for (int i = 0; i < repetitions; i++) {
  118.             r += linear_search(arr, 16, targets[i]);
  119.         }
  120.     } else {
  121.         for (int i = 0; i < repetitions; i++) {
  122.             r += linear_search(arr, size, targets[i]);
  123.         }
  124.     }
  125.     clock_gettime(CLOCK_MONOTONIC, &end);
  126.     long linear_time_ns = (end.tv_sec - start.tv_sec) * 1e9 + (end.tv_nsec - start.tv_nsec);
  127.  
  128.     // Linear search no-br benchmark
  129.     clock_gettime(CLOCK_MONOTONIC, &start);
  130.     if (size == 8) {
  131.         for (int i = 0; i < repetitions; i++) {
  132.             r += linear_search_no_branch(arr, size, targets[i]);
  133.         }
  134.     } else if (size == 16) {
  135.         for (int i = 0; i < repetitions; i++) {
  136.             r += linear_search_no_branch(arr, 16, targets[i]);
  137.         }
  138.     } else if (size == 32) {
  139.         for (int i = 0; i < repetitions; i++) {
  140.             r += linear_search_no_branch(arr, 32, targets[i]);
  141.         }
  142.     } else if (size == 64) {
  143.         for (int i = 0; i < repetitions; i++) {
  144.             r += linear_search_no_branch(arr, 64, targets[i]);
  145.         }
  146.     } else {
  147.         for (int i = 0; i < repetitions; i++) {
  148.             r += linear_search_no_branch(arr, size, targets[i]);
  149.         }
  150.     }
  151.     clock_gettime(CLOCK_MONOTONIC, &end);
  152.     long linear_nb_time_ns = (end.tv_sec - start.tv_sec) * 1e9 + (end.tv_nsec - start.tv_nsec);
  153.  
  154.  
  155.     // Binary search benchmark
  156.     clock_gettime(CLOCK_MONOTONIC, &start);
  157.     if (size == 8) {
  158.         for (int i = 0; i < repetitions; i++) {
  159.             r += binary_search(arr, size, targets[i]);
  160.         }
  161.     } else if (size == 16) {
  162.         for (int i = 0; i < repetitions; i++) {
  163.             r += binary_search(arr, size, targets[i]);
  164.         }
  165.     } else {
  166.         for (int i = 0; i < repetitions; i++) {
  167.             r += binary_search(arr, size, targets[i]);
  168.         }
  169.     }
  170.     clock_gettime(CLOCK_MONOTONIC, &end);
  171.     long binary_time_ns = (end.tv_sec - start.tv_sec) * 1e9 + (end.tv_nsec - start.tv_nsec);
  172.  
  173.     // Binary search NB benchmark
  174.     clock_gettime(CLOCK_MONOTONIC, &start);
  175.     if (size == 8) {
  176.         for (int i = 0; i < repetitions; i++) {
  177.             r += binary_search_no_branch_8(arr, targets[i]);
  178.         }
  179.     } else if (size == 16) {
  180.         for (int i = 0; i < repetitions; i++) {
  181.             r += binary_search_no_branch_16(arr, targets[i]);
  182.         }
  183.     } else {
  184.         for (int i = 0; i < repetitions; i++) {
  185.             r += binary_search_no_branch(arr, size, targets[i]);
  186.         }
  187.     }
  188.     clock_gettime(CLOCK_MONOTONIC, &end);
  189.     long binary_nb_time_ns = (end.tv_sec - start.tv_sec) * 1e9 + (end.tv_nsec - start.tv_nsec);
  190.  
  191.  
  192.     // Print results
  193.     // printf("  Array size: %d, repeats: %d\n", size, repetitions);
  194.     printf(
  195.         "Arr size %5d, %6d iters %6s. Time ns/search: linear %6.2f ns | lin no-brnc %6.2f | bin %6.2f | bin no-br %6.2f  r: %d\n",
  196.         size,
  197.         repetitions,
  198.         last ? "last" : "random",
  199.         (double)linear_time_ns / repetitions,
  200.         (double)linear_nb_time_ns / repetitions,
  201.         (double)binary_time_ns / repetitions,
  202.         (double)binary_nb_time_ns / repetitions,
  203.         r
  204.     );
  205.  
  206.     // Cleanup
  207.     free(arr);
  208.     free(targets);
  209. }
  210.  
  211. int main() {
  212.     // Default benchmark configurations
  213.     BenchmarkConfig configs[] = {
  214.         {8, 200000, false},
  215.         {16, 200000, false},
  216.         {32, 100000, false},
  217.         {64, 100000, false},
  218.         {128, 100000, false} ,
  219.         {256, 100000, false},
  220.         {1024, 10000, false},
  221.         {16384, 10000, false},
  222.         {8, 200000, true},
  223.         {16, 200000, true},
  224.         {32, 100000, true},
  225.         {64, 100000, true},
  226.         {16384, 10000, true}
  227.         // Add more configurations here as needed
  228.     };
  229.  
  230.     int num_configs = sizeof(configs) / sizeof(configs[0]);
  231.  
  232.     for (int i = 0; i < num_configs; i++) {
  233.         benchmark_search(configs[i].array_size, configs[i].repetitions, configs[i].last);
  234.     }
  235.  
  236.     int numbers[] = { 0, 10, 20, 30, 40, 50, 60, 70 };
  237.     int targets[] = { 0, 70, 50, 40, 30, 20, 60, 10, 1, 5, 100 };
  238.     for (int i = 0; i < sizeof(targets)/sizeof(int); i++) {
  239.         int target = targets[i];
  240.         printf("Src %d - lin %d, lin NB %d, bin %d, bin NB %d, bin NB 8 %d\n",
  241.             target,
  242.             linear_search(numbers, 8, target),
  243.             linear_search_no_branch(numbers, 8, target),
  244.             binary_search(numbers, 8, target),
  245.             binary_search_no_branch(numbers, 8, target),
  246.             binary_search_no_branch_8(numbers, target)
  247.         );
  248.     }
  249.  
  250.     return 0;
  251. }
  252.  
Advertisement
Add Comment
Please, Sign In to add comment