Advertisement
Guest User

fbsdgj.c

a guest
Feb 12th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.88 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5.  
  6. #ifdef _WIN32
  7. # include <windows.h>
  8. #else
  9. # include <sys/time.h>
  10. # include <sys/resource.h>
  11. #endif
  12.  
  13. double get_time();
  14. void original_merge_sort(int* list, int len, int* sorted);
  15. void insert_sort(int *list, int len, int *sorted);
  16. void optimized_merge_sort(int* list, int len, int* sorted);
  17. void more_optimized_merge_sort(int *list, int len, int *sorted);
  18. void merge(int* left, int l_len, int* right, int r_len, int* sorted);
  19. void print_arr(int* arr, int l);
  20.  
  21. double benchmark(void (*baseline)(int *, int, int *), void (*contender)(int *, int, int *))
  22. { // Returns how many times faster contender is from baseline
  23.   // Uses differential timing: https://youtu.be/vrfYLlR8X8k?t=39m18s
  24.    
  25.     // Prepare samples
  26.     enum { SAMPLE_SIZE = 100000, N = 10 };
  27.     int *samples[N * 4], *samples_sorted[N * 4];
  28.     for(int i = 0; i < N * 4; ++i)
  29.     {
  30.         samples[i] = malloc(SAMPLE_SIZE * sizeof(int));
  31.         samples_sorted[i] = malloc(SAMPLE_SIZE * sizeof(int));
  32.         for(int j = 0; j < SAMPLE_SIZE; ++j)
  33.             samples[i][j] = rand();
  34.     }
  35.    
  36.     // Run baseline 2n times
  37.     double time_2a = 0;
  38.     for(int i = 0; i < N * 2; ++i)
  39.     {
  40.         double startTime = get_time();
  41.         baseline(samples[i], SAMPLE_SIZE, samples_sorted[i]);
  42.         time_2a += get_time() - startTime;
  43.     }
  44.    
  45.     // Run baseline n times and contender n times
  46.     double time_ab = 0;
  47.     for(int i = 0; i < N; ++i)
  48.     {
  49.         double startTime = get_time();
  50.         baseline(samples[2 * N + i], SAMPLE_SIZE, samples_sorted[2 * N + i]);
  51.         time_ab += get_time() - startTime;
  52.     }
  53.     for(int i = 0; i < N; ++i)
  54.     {
  55.         double startTime = get_time();
  56.         contender(samples[3 * N + i], SAMPLE_SIZE, samples_sorted[3 * N + i]);
  57.         time_ab += get_time() - startTime;
  58.     }
  59.    
  60.     // Calculate relative improvement
  61.     double r = time_2a / (2 * time_ab - time_2a) - 1;
  62.    
  63.     // Clean up
  64.     for(int i = 0; i < 4 * N; ++i)
  65.     {
  66.         free(samples[i]);
  67.         free(samples_sorted[i]);
  68.     }
  69.    
  70.     return r;
  71. }
  72.  
  73. int main() {
  74.     srand(time(NULL));
  75.     printf("optimized_merge_sort is %.2f%% faster than original_merge_sort\n",
  76.         benchmark(original_merge_sort, optimized_merge_sort) * 100);
  77.     printf("more_optimized_merge_sort is %.2f%% faster than original_merge_sort\n",
  78.         benchmark(original_merge_sort, more_optimized_merge_sort) * 100);
  79. }
  80.  
  81. void original_merge_sort(int* list, int len, int* sorted) {
  82.     // length of 1 is sorted
  83.     if (len == 1) {
  84.         *sorted = *list;
  85.         return;
  86.     }
  87.  
  88.     // split into two sub lists
  89.     int l_len = len / 2, r_len = (len+1) / 2;
  90.     int left[l_len], right[r_len];
  91.     for (int i=0; i<len; i++) {
  92.         if (i < l_len)
  93.             left[i] = list[i];
  94.         else
  95.             right[i-l_len] = list[i];
  96.     }
  97.  
  98.     // original_merge_sort left and right lists
  99.     //int *sl, *sr;
  100.     int sl[l_len], sr[r_len];
  101.     original_merge_sort(left, l_len, sl);
  102.     original_merge_sort(right, r_len, sr);
  103.  
  104.     // merge
  105.     merge(sl, l_len, sr, r_len, sorted);
  106. }
  107.  
  108. void merge(int* left, int l_len, int* right, int r_len, int* sorted) {
  109.     int i=0, l=0, r=0;
  110.     // populate the buffer
  111.     while (l<l_len && r<r_len)
  112.         sorted[i++] = (left[l] <= right[r]) ? left[l++] : right[r++];
  113.  
  114.     //handle remaining elements
  115.     while (l<l_len)
  116.         sorted[i++] = left[l++];
  117.     while (r<r_len)
  118.         sorted[i++] = right[r++];
  119. }
  120.  
  121. void print_arr(int* arr, int l) {
  122.     for (int i=0; i<l; i++)
  123.         printf("%d ", arr[i]);
  124.     printf("\n");
  125. }
  126.  
  127. void insert_sort(int *list, int len, int *sorted)
  128. {
  129.     memcpy(sorted, list, len * sizeof(int));
  130.     for(int i = 1; i < len; ++i)
  131.     {
  132.         int j = i, key = sorted[j];
  133.         while(key < sorted[j-1] && j > 0)
  134.         {
  135.             sorted[j] = sorted[j-1];
  136.             --j;
  137.         }
  138.         sorted[j] = key;
  139.     }      
  140. }
  141.  
  142. void optimized_merge_sort(int *list, int len, int *sorted)
  143. {
  144.     if (len <= 1) {
  145.         if(len == 1)
  146.             *sorted = *list;
  147.         return;
  148.     }
  149.    
  150.     // You don't need to split into two lists explicitly,
  151.     // because list is read-only anyway
  152.     int l_len = len / 2, r_len = (len+1) / 2,
  153.         sl[l_len], sr[r_len];
  154.     optimized_merge_sort(list, l_len, sl);
  155.     optimized_merge_sort(list + l_len, r_len, sr);
  156.    
  157.     merge(sl, l_len, sr, r_len, sorted);
  158. }
  159.  
  160. void more_optimized_merge_sort(int *list, int len, int *sorted)
  161. {
  162.     if (len <= 1) {
  163.         if(len == 1)
  164.             *sorted = *list;
  165.         return;
  166.     }
  167.    
  168.     // Use insert sort for sufficiently small lists, because it has better
  169.     // constants. Play around with this number and see how speed changes
  170.     if(len <= 20) {
  171.         insert_sort(list, len, sorted);
  172.         return;
  173.     }
  174.  
  175.     int l_len = len / 2, r_len = (len+1) / 2,
  176.         sl[l_len], sr[r_len];
  177.     more_optimized_merge_sort(list, l_len, sl);
  178.     more_optimized_merge_sort(list + l_len, r_len, sr);
  179.    
  180.     merge(sl, l_len, sr, r_len, sorted);
  181. }
  182.  
  183. double get_time()
  184. {
  185.  
  186. #ifdef _WIN32
  187.  
  188.     LARGE_INTEGER t, f;
  189.     QueryPerformanceCounter(&t);
  190.     QueryPerformanceFrequency(&f);
  191.     return (double)t.QuadPart / (double)f.QuadPart;
  192.    
  193. #else
  194.    
  195.     struct timeval t;
  196.     gettimeofday(&t, NULL);
  197.     return t.tv_sec + t.tv_usec*1e-6;
  198.    
  199. #endif
  200.  
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement