1 /* 2 * Copyright (c) 2000-2001, 2004 Proofpoint, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 */ 9 10 #include <sm/gen.h> 11 SM_RCSID("@(#)$Id: b-strcmp.c,v 1.15 2013-11-22 20:51:42 ca Exp $") 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <unistd.h> 15 #include <sys/types.h> 16 #include <sm/time.h> 17 #include <sm/string.h> 18 19 #define toseconds(x, y) (x.tv_sec - y.tv_sec) 20 #define SIZE 512 21 #define LOOPS 4000000L /* initial number of loops */ 22 #define MAXTIME 30L /* "maximum" time to run single test */ 23 24 void fatal __P((char *)); 25 void purpose __P((void)); 26 int main __P((int, char *[])); 27 28 void 29 fatal(str) 30 char *str; 31 { 32 perror(str); 33 exit(1); 34 } 35 36 void 37 purpose() 38 { 39 printf("This program benchmarks the performance differences between\n"); 40 printf("strcasecmp() and sm_strcasecmp().\n"); 41 printf("These tests may take several minutes to complete.\n"); 42 } 43 44 int 45 main(argc, argv) 46 int argc; 47 char *argv[]; 48 { 49 long a; 50 int k; 51 bool doit = false; 52 long loops; 53 long j; 54 long one, two; 55 struct timeval t1, t2; 56 char src1[SIZE], src2[SIZE]; 57 58 # define OPTIONS "d" 59 while ((k = getopt(argc, argv, OPTIONS)) != -1) 60 { 61 switch ((char) k) 62 { 63 case 'd': 64 doit = true; 65 break; 66 67 default: 68 break; 69 } 70 } 71 72 if (!doit) 73 { 74 purpose(); 75 printf("If you want to run it, specify -d as option.\n"); 76 return 0; 77 } 78 79 /* Run-time comments to the user */ 80 purpose(); 81 printf("\n"); 82 for (k = 0; k < 3; k++) 83 { 84 switch (k) 85 { 86 case 0: 87 (void) sm_strlcpy(src1, "1234567890", SIZE); 88 (void) sm_strlcpy(src2, "1234567890", SIZE); 89 break; 90 case 1: 91 (void) sm_strlcpy(src1, "1234567890", SIZE); 92 (void) sm_strlcpy(src2, "1234567891", SIZE); 93 break; 94 case 2: 95 (void) sm_strlcpy(src1, "1234567892", SIZE); 96 (void) sm_strlcpy(src2, "1234567891", SIZE); 97 break; 98 } 99 printf("Test %d: strcasecmp(%s, %s) versus sm_strcasecmp()\n", 100 k, src1, src2); 101 loops = LOOPS; 102 for (;;) 103 { 104 j = 0; 105 if (gettimeofday(&t1, NULL) < 0) 106 fatal("gettimeofday"); 107 for (a = 0; a < loops; a++) 108 j += strcasecmp(src1, src2); 109 if (gettimeofday(&t2, NULL) < 0) 110 fatal("gettimeofday"); 111 one = toseconds(t2, t1); 112 printf("\tstrcasecmp() result: %ld seconds [%ld]\n", 113 one, j); 114 115 j = 0; 116 if (gettimeofday(&t1, NULL) < 0) 117 fatal("gettimeofday"); 118 for (a = 0; a < loops; a++) 119 j += sm_strcasecmp(src1, src2); 120 if (gettimeofday(&t2, NULL) < 0) 121 fatal("gettimeofday"); 122 two = toseconds(t2, t1); 123 printf("\tsm_strcasecmp() result: %ld seconds [%ld]\n", 124 two, j); 125 126 if (abs(one - two) > 2) 127 break; 128 loops += loops; 129 if (loops < 0L || one > MAXTIME) 130 { 131 printf("\t\t** results too close: no decision\n"); 132 break; 133 } 134 else 135 { 136 printf("\t\t** results too close redoing test %ld times **\n", 137 loops); 138 } 139 } 140 } 141 142 printf("\n\n"); 143 printf("Interpreting the results:\n"); 144 printf("\tFor differences larger than 2 seconds, the lower value is\n"); 145 printf("\tbetter and that function should be used for performance\n"); 146 printf("\treasons.\n\n"); 147 printf("This program will re-run the tests when the difference is\n"); 148 printf("less than 2 seconds.\n"); 149 printf("The result will vary depending on the compiler optimization\n"); printf("level used. Compiling the sendmail libsm library with a\n"); 150 printf("better optimization level can change the results.\n"); 151 return 0; 152 } 153