Originally Posted by
jim mcnamara
Take this and rewrite it so it's just as fast without goto
Code:
#include <stdio.h>
#include <string.h>
#include <time.h>
typedef char chartype;
char *
old_strstr (const char *phaystack, const char *pneedle)
{
register const unsigned char *haystack, *needle;
register chartype b, c;
haystack = (const unsigned char *) phaystack;
needle = (const unsigned char *) pneedle;
b = *needle;
if (b != '\0')
{
haystack--; /* possible ANSI violation */
do
{
c = *++haystack;
if (c == '\0')
goto ret0;
}
while (c != b);
c = *++needle;
if (c == '\0')
goto foundneedle;
++needle;
goto jin;
for (;;)
{
register chartype a;
register const unsigned char *rhaystack, *rneedle;
do
{
a = *++haystack;
if (a == '\0')
goto ret0;
if (a == b)
break;
a = *++haystack;
if (a == '\0')
goto ret0;
shloop:; }
while (a != b);
jin: a = *++haystack;
if (a == '\0')
goto ret0;
if (a != c)
goto shloop;
rhaystack = haystack-- + 1;
rneedle = needle;
a = *rneedle;
if (*rhaystack == a)
do
{
if (a == '\0')
goto foundneedle;
++rhaystack;
a = *++needle;
if (*rhaystack != a)
break;
if (a == '\0')
goto foundneedle;
++rhaystack;
a = *++needle;
}
while (*rhaystack == a);
needle = rneedle; /* took the register-poor approach */
if (a == '\0')
break;
}
}
foundneedle:
return (char*) haystack;
ret0:
return 0;
}
char *my_strstr(const char *haystack, const char *needle)
{
if ( !*needle )
{
return (char*)haystack;
}
for ( ; *haystack; ++haystack )
{
if ( *haystack == *needle )
{
const char *h = haystack, *n = needle;
for ( ; *h && *n; ++h, ++n )
{
if ( *h != *n )
{
break;
}
}
if ( !*n )
{
return (char*)haystack;
}
}
}
return 0;
}
int main(void)
{
const char text[] = "The quick brown fox jumps over the lazy dog.";
const char word[] = "fox";
char *(*function[])(const char *, const char *) = {old_strstr, my_strstr, strstr};
size_t j;
for ( j = 0; j < sizeof function / sizeof *function; ++j )
{
char *found;
int i;
double elapsed;
clock_t start = clock();
for ( i = 0; i < 10000000; ++i )
{
found = function[j](text, word);
}
elapsed = clock() - start;
elapsed /= CLOCKS_PER_SEC;
printf("elapsed = %g\n", elapsed);
if ( found )
{
puts(found);
}
}
return 0;
}
/* Borland 5.5
elapsed = 2.013
fox jumps over the lazy dog.
elapsed = 1.362
fox jumps over the lazy dog.
elapsed = 1.192
fox jumps over the lazy dog.
*/
/* MSVC6
elapsed = 3.284
fox jumps over the lazy dog.
elapsed = 2.764
fox jumps over the lazy dog.
elapsed = 0.862
fox jumps over the lazy dog.
*/
/* Dev-C++
elapsed = 1.792
fox jumps over the lazy dog.
elapsed = 1.583
fox jumps over the lazy dog.
elapsed = 0.811
fox jumps over the lazy dog.
*/
The optimizations that are made for a particular system may not necessarily be optimal everywhere.