home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 08 / ctest / ctest.c next >
Text File  |  1991-05-20  |  6KB  |  179 lines

  1. /* ctest.c - a couple of benchmarks for c */
  2.  
  3. /* The first is a procedure call benchmark that computes fibonacci
  4.    numbers. */
  5.  
  6. /* The second is a floating point benchmark derived from: */
  7.  
  8. /* SIERP.C -- (C) 1990 by Dick Oliver, R1 Box 5140, Morrisville, VT  05661
  9.    A program to "draw" and "paint" Sierpinksi's Triangle, defined by a
  10.    "seed" (or "parent") shape and three transformations of that shape
  11.    ("children").  You may copy, modify, and recompile this source code
  12.    as you please, as long as you do not sell it or any product produced
  13.    from any part of it.  The author makes no claims as to readability or
  14.    suitability for a particular task, but I'll be happy to give advice
  15.    and assistance. */
  16.  
  17. #include <stdio.h>   /* For getch() */
  18. #include <math.h>    /* For cos() and sin() */
  19. #include <time.h>
  20.  
  21. #define CLOOPCNT    100    /* default number of call iterations */
  22. #define TLOOPCNT    100    /* default number of tree iterations */
  23.  
  24. void init_graphics(void);
  25. void done_graphics(void);
  26. void clear_screen(void);
  27. void moveto(int x, int y);
  28. void lineto(int x, int y);
  29. long atol(char *str);
  30.  
  31. #define NPOINTS 4    /* Number of points on the "parent" polygon */
  32. #define NTRANS  6    /* Number of transformed "children" */
  33. #define NLEVELS 5    /* Number of levels to draw */
  34. #define COUNT 10000  /* Number of dots to paint */
  35. #define CENTERX 320  /* Center of the screen */
  36. #define CENTERY 350
  37. #define SEEDX 6,20,-6,-12  /* The "parent" polygon */
  38. #define SEEDY -120,120,120,-120
  39.  
  40. /* The tranformations which define the "children" */
  41.  
  42. #define MOVEX -41.2,36.9,5.13,-14.64,2.2,40.07 /* Displacement */
  43. #define MOVEY 14.987,-61.31,7.10,-32.33,-50.46
  44. #define SIZEX  0.39,0.41,0.52,0.35,0.86,0.37 /* Size change */
  45. #define SIZEY  0.39,0.31,0.17,0.24,0.79,0.42
  46. #define SPINX  5.62,0.61,6.15,5.43,3.27,0.54 /* Rotation */
  47. #define SPINY  4.91,1.27,0.13,4.71,6.28,1.4
  48.  
  49. int seedx[NPOINTS] = {SEEDX},   /* The "parent" polygon */
  50.     seedy[NPOINTS] = {SEEDY};
  51.  
  52.       /* The tranformations which define the "children" */
  53. float movex[NTRANS] = {MOVEX},  /* Displacement */
  54.       movey[NTRANS] = {MOVEY},
  55.       sizex[NTRANS] = {SIZEX},  /* Size change */
  56.       sizey[NTRANS] = {SIZEY},
  57.       spinx[NTRANS] = {SPINX},  /* Rotation */
  58.       spiny[NTRANS] = {SPINY},
  59.  
  60.       /* The transformation matrix T, computed from the above variables */
  61.       Ta[NTRANS], Tb[NTRANS], Tc[NTRANS], Td[NTRANS];
  62.  
  63. /* Function prototypes */
  64. double call_test(long loopcnt);
  65. int fib(int n);
  66. double tree_test(long loopcnt);
  67. void draw_tree(void);
  68. void draw(float a, float b, float c, float d, float mx, float my, int iter);
  69.  
  70. void main(int argc, char **argv)
  71. {
  72.     double elapsed;
  73.     long loopcnt;
  74.     FILE *fp;
  75.     int i;
  76.  
  77.     /* append to the results file */
  78.     if ((fp = fopen("ctest.out","a")) == NULL)
  79.     exit(1);
  80.  
  81.     /* show the command line */
  82.     for (i = 0; i < argc; ++i)
  83.     fprintf(fp,"%s ",argv[i]);
  84.     putc('\n',fp);
  85.  
  86.     /* do the call test */
  87.     loopcnt = (argc > 1 ? atol(argv[1]) : CLOOPCNT);
  88.     elapsed = call_test(loopcnt);
  89.     fprintf(fp,"%g fib(25)'s/second\n",(double)loopcnt / elapsed);
  90.  
  91.     /* do the tree test */
  92.     loopcnt = (argc > 2 ? atol(argv[2]) : TLOOPCNT);
  93.     elapsed = tree_test(loopcnt);
  94.     fprintf(fp,"%g trees/second\n",(double)loopcnt / elapsed);
  95. }
  96.  
  97. double call_test(long loopcnt)
  98. {
  99.     time_t start,end;
  100.     start = time((time_t)0);
  101.     while (--loopcnt >= 0L)
  102.     (void)fib(25);
  103.     end = time((time_t)0);
  104.     return difftime(end,start);
  105. }
  106.  
  107. int fib(int n)
  108. {
  109.     return n < 2 ? n : fib(n - 1) + fib(n - 2);
  110. }
  111.  
  112. double tree_test(long loopcnt)
  113. {
  114.     time_t start,end;
  115.  
  116.     init_graphics();    /* Initialize the screen */
  117.  
  118.     start = time((time_t)0);
  119.     while (--loopcnt >= 0L) {
  120.     clear_screen();
  121.     draw_tree();
  122.     }
  123.     end = time((time_t)0);
  124.  
  125.     done_graphics();    /* Go back to text mode and exit */
  126.  
  127.     return difftime(end,start);
  128. }
  129.  
  130. void draw_tree(void)
  131. {   int t;
  132.  
  133.     /* Compute a,b,c,d from the move, size, and spin variables */
  134.     for (t = 0; t < NTRANS; t++)
  135.     {   Ta[t] =   sizex[t] * cos(spinx[t]);
  136.         Tb[t] = - sizey[t] * sin(spiny[t]);
  137.         Tc[t] =   sizex[t] * sin(spinx[t]);
  138.         Td[t] =   sizey[t] * cos(spiny[t]);
  139.     }
  140.  
  141.     /* Invoke draw with an initial transformation to move the triangle
  142.        to the center of the screen, unchanged in size or rotation */
  143.     draw(1.0, 0.0, 0.0, 1.0, (float) CENTERX, (float) CENTERY, NLEVELS);
  144. }
  145.  
  146.  
  147. /* This recursive routine draws one "parent" polygon, then calls itself
  148.    to draw the "children" using the transformations defined above */
  149.  
  150. void draw(float a, float b, float c, float d, float mx, float my, int iter)
  151. {   int t;
  152.     iter--;   /* Count one more level of drawing depth */
  153.     {     /* Use a,b,c,d,mx,my to transform the polygon */
  154.         float x1, y1;  /* Point on the parent */
  155.         int p, x2[NTRANS], y2[NTRANS]; /* Points on the child */
  156.         for (p = 0; p < NPOINTS; p++)
  157.         {   x1 = seedx[p];
  158.         y1 = seedy[p];
  159.         x2[p] = a * x1 + b * y1 + mx;
  160.         y2[p] = c * x1 + d * y1 + my;
  161.         }
  162.         /* Now draw the new polygon on the screen */
  163.         moveto(x2[NPOINTS - 1], y2[NPOINTS - 1]);
  164.         for (p = 0; p < NPOINTS; p++) lineto(x2[p], y2[p]);
  165.     }
  166.     if (iter < 0) return;  /* If we're at the deepest level, back out */
  167.  
  168.     /* Do a recursive call for each "child" of the polygon we just drew */
  169.     for (t = 0; t < NTRANS; t++)
  170.     {   draw(Ta[t] * a + Tc[t] * b,
  171.          Tb[t] * a + Td[t] * b,
  172.          Ta[t] * c + Tc[t] * d,
  173.          Tb[t] * c + Td[t] * d,
  174.          movex[t] * a + movey[t] * b + mx,
  175.          movex[t] * c + movey[t] * d + my,
  176.          iter);
  177.     }
  178. }
  179.