
#include <stdio.h>
#include <bios.h>
#include <string.h>

#define LIMIT 70000L

#define INIT                  \
long i;                  \
long t = biostime(0,0)

#define TEST(x)               \
INIT;                    \
for(i=0; i<LIMIT; i++){  \
     x;                  \
     }                   \
return (int)(biostime(0,0)-t)

#define Access(x,y) \
printf("Accessing %s(): result = %d\n", #x,
        elapsed[y]=x() )

typedef struct anything
    {
char field1[50],
     field2[50],
     field3[50],
     field4[50];
} anything;

anything s_object, *s_pointer=&s_object;

char *DestArray[4];
char *SourceArray[4];
char *access;
int  j=0;

enum list { STRUCTURE, ARRAY, BOTH, EMPTY, ONELOOP,
            TWOLOOPS, S_OBJECT };

int UsingS_Object(void)
{
TEST(     access = (char *)&s_object.field1;
          access = (char *)&s_object.field2;      
          access = (char *)&s_object.field3;
          access = (char *)&s_object.field4;);  
}

int UsingStructure(void)
   {
    TEST(      access = s_pointer->field1;
          access = s_pointer->field2;      
          access = s_pointer->field3;
          access = s_pointer->field4;        );

int UsingArray(void)
   {
TEST(     access = SourceArray[0];
          access = SourceArray[1];
          access = SourceArray[2];
          access = SourceArray[3];           );
}

zint UsingStrucAndArrayBoth(void)
   {
    TEST(      access = s_pointer->field1;
          access = s_pointer->field2;      
          access = s_pointer->field3;
          access = s_pointer->field4;       

          access = SourceArray[0];
          access = SourceArray[1];
          access = SourceArray[2];
          access = SourceArray[3]; );

    }

int EmptyLoop(void)
    {
TEST( ; );
}

int LoopToLoop(void)
    {
TEST( for(j=0; j<4; j++){ DestArray[j] =
                SourceArray[j]; } );
}

int OneLoop(void)
{
TEST( for(j=0; j<4; j++){ access = SourceArray[j]; } );
}

void analyze(int *times)
{
int total = times[STRUCTURE] + times[ARRAY];
int difference = total - times[BOTH];

printf("\n1. Sum of time for (UsingStructure + \
UsingArray) = %d\n", total );

printf("2. Sum less time for both in one loop = %d\n", 
      difference );
printf("3. Time to do an empty loop = %d\n",
      times[EMPTY] );
printf("4. Error (item 3 less item 2 should be near \
zero) = %d\n", 
      times[EMPTY]-difference );
}

void CompareAccessTimes(void)
{
int elapsed[10];

Access(UsingS_Object,S_OBJECT);
Access(UsingStructure,STRUCTURE);
Access(UsingArray, ARRAY );
Access(UsingStrucAndArrayBoth, BOTH);
Access(EmptyLoop, EMPTY);
Access(LoopToLoop,TWOLOOPS);
Access(OneLoop,ONELOOP);

analyze(elapsed);
}

void VerifyContents(void)
{
int i;

puts("The data to be accessed is as follows:\n");

/*        
printf("The structure contains the following...\n");
printf("\t%s\n\t%s\n\t%s\n\t%s\n",
     s_pointer->field1,
     s_pointer->field2,
     s_pointer->field3,     
     s_pointer->field4);
*/
printf("\nThe array provides access to...\n");
for(i=0; i<4; i++)
     {
     printf("\t%s\n", SourceArray[i] );
     }
puts("\nEach function returns the count of clock ticks."\
     "The lower the better.\n);
}

void main(void)
{
    
printf("In this example, the size of a data pointer is %d,",
      sizeof(char*));  
printf("and the size\nof a function pointer is %d\n", 
      sizeof(main) );

/*   initialize the structure */

strcpy(s_pointer->field1,"This is field one");
strcpy(s_pointer->field2,"Here's the second field");
strcpy(s_pointer->field3,"Field Three at your service");
strcpy(s_pointer->field4,"Art was here");    

/* initialize the purportedly slower array */

SourceArray[0] = s_pointer->field1; 
SourceArray[0] = s_pointer->field2;
SourceArray[0] = s_pointer->field3;
SourceArray[0] = s_pointer->field4;

VerifyContents();

CompareAccessTimes();
}

