/* Benchmark versions of string-lower-casing function */ #include #include #include #include "clock.h" #include "fcyc.h" #define LSIZE 500000 #define LINCR 20000 #define ESIZE (1<<20) #define EMIN (1<<14) #define ASIZE (LSIZE < ESIZE ? ESIZE : LSIZE) /* Keep track of a number of different procedures */ #define MAX_BENCHMARKS 10 static char data[ASIZE]; static double clock_rate = 0.0; static void init() { long i; for (i = 0; i < ASIZE; i++) data[i] = 'a' + i%26; } static void set_len(long len) { data[len] = '\0'; } static void unset_len(long len) { data[len] = 'a' + len%26; } /* $begin strfuns */ /* Convert string to lowercase: slow */ void lower1(char *s) { long i; for (i = 0; i < strlen(s); i++) if (s[i] >= 'A' && s[i] <= 'Z') s[i] -= ('A' - 'a'); } /* Convert string to lowercase: faster */ void lower2(char *s) { long i; long len = strlen(s); for (i = 0; i < len; i++) if (s[i] >= 'A' && s[i] <= 'Z') s[i] -= ('A' - 'a'); } /* Convert string to lowercase: without strlen */ /* This is the code generated by GCC for lower1, with optimization level >= 2 */ void lower3(char *s) { long i; for (i = 0; s[i] != 0; i++) if (s[i] >= 'A' && s[i] <= 'Z') s[i] -= ('A' - 'a'); } /* Sample implementation of library function strlen */ /* Compute length of string */ size_t strlen(const char *s) { long length = 0; while (*s != '\0') { s++; length++; } return length; } /* $end strfuns */ void test_lower1(long *lenp) { long len = *lenp; set_len(len); lower1(data); unset_len(len); } void test_lower2(long *lenp) { long len = *lenp; set_len(len); lower2(data); unset_len(len); } /* Perform test of function */ static double run_test(test_funct fun, long len) { double cycs; double time; set_fcyc_compensate(0); cycs = fcyc(fun,&len); time = cycs/(clock_rate*1e6); return time; } void linear() { long size; printf("Length\tlower1\tlower2\n"); for (size = LINCR; size <= LSIZE; size+=LINCR) { printf("%ld", size); printf("\t%f", run_test(test_lower1, size)); printf("\t%f\n", run_test(test_lower2, size)); } } void expo() { long size; for (size = EMIN; size <= ESIZE; size += size) printf("& %ld ", size); printf(" \\\\\n"); for (size = EMIN; size <= ESIZE; size += size) printf("& %.2f ", run_test(test_lower1, size)); printf(" \\\\\n"); for (size = EMIN; size <= ESIZE; size += size) printf("& %.4f ", run_test(test_lower2, size)); printf(" \\\\\n"); } int main(int argc, char *argv[]) { init(); clock_rate = mhz(1); if (argc > 1) expo(); else linear(); return 0; }