Advertisement
gbulmer

stackoverflow-9846681.c

Mar 25th, 2012
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.27 KB | None | 0 0
  1. /* Testing sort - stackoverflow topic 9846681
  2.  * Compares sorts on float 'val':
  3.  *  -q qsort,
  4.  *  -m mergesort,
  5.  *  -h heapsort
  6.  * Reordering could be by the same type of sort on idx - default or
  7.  *  -c by copying to a second array
  8.  *
  9.  * Note: timing is Mac OS X specific, and uses mach timing mechanisms.
  10.  *
  11.  * Copyright G Bulmer 2012
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <sys/time.h>
  17. #include <sys/resource.h>
  18. #include <mach/mach.h>
  19. #include <mach/mach_time.h>
  20.  
  21.  
  22. static mach_timebase_info_data_t sTimebaseInfo; /* OS X nanoseconds clock */
  23. static struct timeval start_time;           /* wall clock start time */
  24. static struct timeval end_time;             /* wall clock end time */
  25. static struct rusage initial_rUsage;        /* initial time (resource) use */
  26. static struct rusage final_rUsage;          /* final time (resource) use */
  27.  
  28. /* Calculate the duration measured in mach absolute time, nanoseconds */
  29. double duration(uint64_t start, uint64_t end)
  30. {
  31.     uint64_t elapsed = end - start;
  32.    
  33.     return (double) (elapsed * sTimebaseInfo.numer / sTimebaseInfo.denom)
  34.                             / 1000000000.0;
  35. }
  36.  
  37. /* Test Data to be sorted and copied */
  38. struct ValStruct {
  39.     float val;
  40.     /* float val2; */
  41.     int idx;
  42. };
  43.  
  44. struct Val2Struct {
  45.     float val;
  46.     float val2;
  47.     /* int idx; */
  48. };
  49.  
  50. #define MAX (40000000)
  51. static struct ValStruct data[MAX];
  52. static struct Val2Struct dataIdx[MAX];
  53.  
  54.  
  55. static int ValOrdering(const void* const v1, const void* const v2)
  56. {
  57.     if (((struct ValStruct*) v1)->val < ((struct ValStruct*) v2)->val)
  58.         return -1;
  59.    
  60.     if (((struct ValStruct*) v1)->val> ((struct ValStruct*) v2)->val)
  61.         return 1;
  62.    
  63.     return 0;
  64. }
  65.  
  66. static int IndexOrdering(const void* const v1, const void* const v2)
  67. {
  68.     return ((struct ValStruct*) v1)->idx- ((struct ValStruct*) v2)->idx;
  69. }
  70.  
  71.  
  72. int main (int argc, const char * argv[]) {
  73.     char sorttype = 'q';   /* sort type - default is quicksort     */
  74.     char idxtype = '\0';   /* reorganise idx by sort ('c' == copy) */
  75.    
  76.     for (int i=1; i<argc; ++i) {
  77.         /* printf("got %s\n", argv[i]); */
  78.         if (*argv[i] == '-') {
  79.             char arg = *(argv[i]+1);
  80.             /* printf("got %s arg=%c\n", argv[1], arg); */
  81.             if (arg == 'q') {
  82.                 sorttype = 'q';
  83.             } else if (arg == 'm') {
  84.                 sorttype = 'm';
  85.             } else if (arg == 'h') {
  86.                 sorttype = 'h';
  87.             } else if (arg == 'c') {
  88.                 idxtype = 'c';
  89.             } else {
  90.                 fprintf(stderr, "unrecognised argument '%c'\n", arg);
  91.                 exit(1);
  92.             }
  93.         }
  94.     }
  95.        
  96.     /* Initialise with random data - so their will be some variation */
  97.     for (int i=0; i<MAX; ++i) {
  98.         data[i].val = lrand48();
  99.         data[i].idx = i;
  100.     }
  101.    
  102.     /* Print enough information to identify the type of sort and data set */
  103.     if (sorttype  == 'q') {
  104.         printf("qsort(data, number-of-elements=%d, element-size=%d)\n",
  105.                                                 MAX, sizeof(data[0]));
  106.     } else if (sorttype  == 'm') {
  107.         printf("mergesort(data, number-of-elements=%d, element-size=%d)\n",
  108.                                                 MAX, sizeof(data[0]));
  109.     } else if (sorttype  == 'h') {
  110.         printf("heapsort(data, number-of-elements=%d, element-size=%d)\n",
  111.                                                 MAX, sizeof(data[0]));
  112.     }
  113.    
  114.     uint64_t start;         /* start, intermediate and final timing points */
  115.     uint64_t mid_val;
  116.     uint64_t mid_idx;
  117.     uint64_t end;      
  118.     (void) mach_timebase_info(&sTimebaseInfo); /* Critical that this is done! */
  119.  
  120.     gettimeofday(&start_time, NULL); /* only to cross-check total duration */
  121.     getrusage(RUSAGE_SELF, &initial_rUsage);    /* get CPU usage so far */
  122.  
  123.     start = mach_absolute_time();
  124.  
  125.     if (sorttype  == 'q') {
  126.         qsort(data, MAX, sizeof(data[0]), ValOrdering);
  127.     } else if (sorttype  == 'm') {
  128.         mergesort(data, MAX, sizeof(data[0]), ValOrdering);
  129.     } else if (sorttype  == 'h') {
  130.         heapsort(data, MAX, sizeof(data[0]), ValOrdering);
  131.     }
  132.    
  133.     mid_val = mach_absolute_time();
  134.  
  135.     if (idxtype = 'c') {            /* copy by index rather than sort */
  136.         for (int i=0; i<MAX; ++i) {
  137.             dataIdx[data[i].idx].val = data[i].val;
  138.             dataIdx[data[i].idx].val2 = lrand48(); /* simulate calculation */
  139.         }
  140.     } else {
  141.         if (sorttype  == 'q') {
  142.             qsort(data, MAX, sizeof(data[0]), IndexOrdering);
  143.         } else if (sorttype  == 'm') {
  144.             mergesort(data, MAX, sizeof(data[0]), IndexOrdering);
  145.         } else if (sorttype  == 'h') {
  146.             heapsort(data, MAX, sizeof(data[0]), IndexOrdering);
  147.         }
  148.     }
  149.    
  150.     mid_idx = mach_absolute_time();
  151.  
  152.         /* time sort with in-order data, maybe handy to know */
  153.     if (sorttype  == 'q') {
  154.         qsort(data, MAX, sizeof(data[0]), ValOrdering);
  155.     } else if (sorttype  == 'm') {
  156.         mergesort(data, MAX, sizeof(data[0]), ValOrdering);
  157.     } else if (sorttype  == 'h') {
  158.         heapsort(data, MAX, sizeof(data[0]), ValOrdering);
  159.     }
  160.    
  161.    
  162.     end = mach_absolute_time();
  163.     getrusage(RUSAGE_SELF, &final_rUsage);
  164.     gettimeofday(&end_time, NULL);      /* only to cross-check total duration */
  165.  
  166.    
  167.     printf("Sorting by val - duration = %f\n", duration(start, mid_val));
  168.     if (idxtype = 'c') {            /* copy by index rather than sort */
  169.         printf("Re-order to idx by copying - duration = %f\n",
  170.                                                 duration(mid_val, mid_idx));
  171.     } else {
  172.         printf("Sort to idx - duration = %f\n", duration(mid_val, mid_idx));
  173.     }
  174.     printf("Sort in-order data - duration = %f\n", duration(mid_idx, end));
  175.     printf("Total duration = %f\n", duration(start, end));
  176.  
  177.     /* long double makes arithmetic easier, calculate in micro-seconds (usec) */
  178.     long double utime_usec = 1000000.0
  179.                                 * ((double)final_rUsage.ru_utime.tv_sec
  180.                                       - (double)initial_rUsage.ru_utime.tv_sec)
  181.                                   + (double)final_rUsage.ru_utime.tv_usec
  182.                                       - (double)initial_rUsage.ru_utime.tv_usec;
  183.  
  184.     long double stime_usec = 1000000.0
  185.                                 * ((double)final_rUsage.ru_stime.tv_sec
  186.                                     - (double)initial_rUsage.ru_stime.tv_sec)
  187.                                   + (double)final_rUsage.ru_stime.tv_usec
  188.                                      - (double)initial_rUsage.ru_stime.tv_usec;          
  189.  
  190.    
  191.     /* We can use the value from gettimeof day to cross check duration
  192.      * but it is confusing, so leave it as a debug aid.
  193.      */
  194. #if 0
  195.      long double rtime_usec = 1000000.0
  196.                     * ((double)end_time.tv_sec - (double)start_time.tv_sec)
  197.                         + (double)end_time.tv_usec - (double)start_time.tv_usec;
  198.      printf("Real Time (cross check): %.6Lf\n", rtime_usec/1000000.0);
  199. #endif
  200.      
  201.     printf("User Time: %.6Lf\n", utime_usec/1000000.0);
  202.     printf("System Time: %.6Lf\n", stime_usec/1000000.0);
  203.    
  204.     printf("Done Smallsort\n");
  205.     return 0;
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement