几种strstr的比较

这是几种字符串匹配的算法实现。其中有bm算法,bf算法,以及sse实现的改进算法。和glibc系统库比较,最终没有像想想那样sse最快,还是系统库的最快。

 

/

*
 * My personal strstr() implementation that beats most other algorithms.
 * Until someone tells me otherwise, I assume that this is the
 * fastest implementation of strstr() in C.
 * I deliberately chose not to comment it.  You should have at least
 * as much fun trying to understand it, as I had to write it :-).
 *
 * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
#include "stdlib.h"
#include "stdio.h"
typedef unsigned chartype;

 


char *strstrBerg (const char *phaystack,const char *pneedle)
{
 const unsigned char *haystack, *needle;
 chartype b;
 const unsigned char *rneedle;

 haystack = (const unsigned char *) phaystack;

 if ((b = *(needle = (const unsigned char *) pneedle)))
 {
  chartype c;
  haystack--;       /* possible ANSI violation */
  {
   chartype a;
   do
    if (!(a = *++haystack))
     goto ret0;/* if haystack ends, return 0 */
   while (a != b); /* find the first postion that equals */
  }

  /* first char equals, go on */
  if (!(c = *++needle))
   goto foundneedle; /* only one char in needle, found it */
  ++needle;/* needle go to 3rd char */
  goto jin;

  for (;;)
  {
   {
    chartype a;
    if (0)
    jin:
    {
     if ((a = *++haystack) == c)/* check if the second char in needle equals*/
      goto crest;
    }
    else
     a = *++haystack;
    do
    {
     for (; a != b; a = *++haystack)/* search haystack to find a char equals the 1st char of needle */
     {
      if (!a)
       goto ret0;
      if ((a = *++haystack) == b) /* one loop compare 2 chars */
       break;
      if (!a)
       goto ret0;
     }
    }
    while ((a = *++haystack) != c); /* until second char equals */
   }
crest:/* 2 char equals, go on */
   {
    chartype a;
    {
     const unsigned char *rhaystack;
     /* rhaystack =next char, haystack-- set haystack point at the postion to be returned */
     if (*(rhaystack = haystack-- + 1) == (a = *(rneedle = needle)))/* go on comparing from 3rd char of needle */
      do
      {
       if (!a)
        goto foundneedle;
       if (*++rhaystack != (a = *++needle))
        break;
       if (!a)
        goto foundneedle;
      }
      while (*++rhaystack == (a = *++needle));/* until reach a char not equal */
     needle = rneedle; /* took the register-poor aproach ,needle point to 3rd char */
    }
    if (!a)
     break;
   }
  }
 }
foundneedle:
 return (char *) haystack;
ret0:
 return 0;
}

/* String matching by maximal suffices. */
char* strstrToy(const char*haystack, const char*needle) {
  size_t ul;
  if (!*needle)
   return (char*)haystack;
  if (!needle[1])
   return strchr(haystack, *needle);

  /* Here follow some heuristics for finding a reasonable place to start
   * the search, since this code is slower by a decently large constant factor
   * than Stephen van den Berg's code in easy cases, particularly on short
   * strings.
   */
  {
    size_t s;
    /* use naive algorithm on short patterns. */
    for (s = 2; s < 8; s++)
      if (!needle[s])
    return strstrBerg(haystack, needle);

    /* find the first occurrence of needle as a subsequence of haystack. */
    for (s = 0; needle[s]; s++) {
      while (haystack[s] != needle[s] && haystack[s])
    haystack++;
      if (!haystack[s])
    return NULL;
    }
     
    /* look for the first 7 chars of needle in haystack. */
    char foo[8];
    for (s = 0; s < 7; s++)
  foo[s] = needle[s];
    foo[7] = 0;
    haystack = (const char*)strstrBerg(haystack, foo);
    if (haystack == NULL)
  return NULL;
  }

  const char *v;
  /* find a maximal suffix of needle, and store it in v. */
  {
    size_t i, j = 0, p;
    while (1) {
      /* find the longest self-maximal prefix of needle[j...strlen(needle)].
       * i is its end, and p is its period. */
      for (i = j+1, p = 1; needle[i]; i++) {
        if (needle[i] < needle[i - p])
   p = i - j + 1;
        else if (needle[i] > needle[i - p])
   break;
      }
      /* needle[j...i-1] is the longest self-maximal prefix of needle+j. */
      if (needle[i])
    j = i - (i - j) % p;
      else
    break;
    }
    v = needle + j;
    ul = j;
  }

  /* use Stephen's code for short v. */
  if (strlen(v) < 10) {
    const char *prev = haystack;
    const char *hay = haystack + ul;
    while (1) {
      hay = strstrBerg(hay, v);
      if (hay == NULL)
    goto retnull;
      if (hay - prev >= ul && !memcmp(hay - ul, needle, ul))
        return (char*)(hay - ul);
      prev = hay;
      hay++;
    }
  }

  /* now do the searching. */
  {
    size_t p = 1, j = 0;
    const char *hi = haystack+ul;
    const char *prev = haystack;
 
    while (1) {
      /* match pattern characters against text characters. */
      while (v[j] == hi[j] && v[j]) {
        /* The character v[j] breaks the periodicity of v.
         * We therefore have the situation depicted in the following cartoon:
         *
         *            /---p---\            j
         * v: [a b c d|a b c d|a b c d|a b x.............]
         *
         * The period of this string is at least j, so we update p accordingly.
         *
         * Why can't it be less than j?
         * Suppose that the period of v[0...j] were less than j, even though
         * v[j] != v[j - p].  There are two cases:
         *   Case 1: v[j] > v[j - p]
         *       Then v[0...j] is less than v[p...j], since
         *       v[0...j-p-1] = v[p...j-1] while v[j] > v[j-p], a contradiction.
         *   Case 2: v[j] < v[j - p]
         *       Let q be the actual period of v[0...j].
         *       Then v[j % q] < v[j - p].
         *       Thus, v[j - p - (j % q)...j] > v[0...j], since
         *       v[j - p - (j % q)...j - p - 1] = v[0...(j % q) - 1]
         *       while v[j - p] > v[j] = v[j % q].
         *       This is again a contradiction.
         */
        if (j > p && v[j] != v[j-p])
          p = j;
        j++;
      }
 
      if (!v[j]) { /* v matches. */
        if (hi >= prev) {
          if (!memcmp(hi-ul, needle, ul)) /* whole string matches. */
            return (char*)(hi-ul);
          /* u doesn't match. */
        }
        /* else, u cannot possibly match since v was a maximal suffix. */
        prev = hi+ul; /* u doesn't match. set prev accordingly. */
      }
      else if (!hi[j])
    goto retnull;
 
      /* We know that v[0...j] has period p.  We also know that j characters of
       * the text match.  We can therefore shift the pattern over by p, since at
       * least the first p characters of haystack+i must match the first p
       * characters of v.
       */
        hi += p;
      /* Similarly, if we matched the first 2p characters of v, we must match
       * the first p characters of the needle against the first p characters of
       * the haystack, so we shift v by p.
       */
      if (j >= p+p) j -= p;
      else p=1, j = 0;
    }
  }

  retnull:
  return NULL;
}

 

char* MYSQLstrstr(const char *str,const char *search) 

 char *i,*j; 
 char first= *search;
skip: 
 while (*str != '\0') { 
  if (*str++ == first) { 
   i=(char*)str; j=(char*) search+1; 
   while (*j) 
    if (*i++ != *j++)
     goto skip; 
   /* return (str-1); */
   return (char *)str-1; 
  } 
 } 
 return ((char*) 0); 
} /** strstr */

char *strstr_fxxx (char *text, char *pattern)
{
 char *p;
 
    for (p = text; *p; p++)
    {
        char *pp = p, *t = pattern;
        while (*pp == *t && *t)
            pp++, t++;

        if (!*t)
            return p;
    }

    return NULL;
}

#define XSIZE 100
#define ASIZE 256
#define MAX(a,b) (a>b)?a:b
#define SRET(i)  return NULL;

#define STOP 1
#define SEARCH_STOP 1
static int report_default(const char* text, int idx, const char* pat)
{
 return SEARCH_STOP;
}
typedef int (*reportFunc)(const char* text, int idx, const char* pat);
reportFunc report_function = report_default;

/* #define OUTPUT(x) if( report_function(text, x, pat) == STOP ) return (text + (x)); */


void preBmBc(char *pat, int m, int bmBc[]) {
   int i;
 
   for (i = 0; i < ASIZE; ++i)
      bmBc[i] = m;
   for (i = 0; i < m - 1; ++i)
      bmBc[pat[i]] = m - i - 1;
}
 
 
void suffipates(char *pat, int m, int *suff) {
   int f, g, i;
 
   suff[m - 1] = m;
   g = m - 1;
   for (i = m - 2; i >= 0; --i) {
      if (i > g && suff[i + m - 1 - f] < i - g)
         suff[i] = suff[i + m - 1 - f];
      else {
         if (i < g)
            g = i;
         f = i;
         while (g >= 0 && pat[g] == pat[g + m - 1 - f])
            --g;
         suff[i] = f - g;
      }
   }
}
 
void preBmGs(char *pat, int m, int bmGs[]) {
   int i, j, suff[XSIZE];
 
   suffipates(pat, m, suff);
 
   for (i = 0; i < m; ++i)
      bmGs[i] = m;
   j = 0;
   for (i = m - 1; i >= -1; --i)
      if (i == -1 || suff[i] == i + 1)
         for (; j < m - 1 - i; ++j)
            if (bmGs[j] == m)
               bmGs[j] = m - 1 - i;
   for (i = 0; i <= m - 2; ++i)
      bmGs[m - 1 - suff[i]] = m - 1 - i;
}
 
 
char* Sbm2(char *texts, char *pat,int n, int m) {
 int i, j, bmGs[XSIZE], bmBc[ASIZE];
 //   printf("n lenth of bm:%d,m:%d,",n,m);
 unsigned char* text= (unsigned char*) texts;

 /* Preprocessing */
 preBmGs(pat, m, bmGs);
 preBmBc(pat, m, bmBc);
 /* Searching */
 j = 0;
 while (j <= n - m) {
  for (i = m - 1; (i >= 0) && (pat[i] == text[i + j]); --i);
  if (i < 0) {
   if( report_function(text, j, pat) == STOP )
    return (text + (j));
   j += bmGs[0];
  }
  else{
   int skipn = MAX(bmGs[i], bmBc[text[i + j]] - m + 1 + i);
   //if(skipn> m)
    //printf("err\n");
   j += skipn;
  }
 }
 return NULL;
}

char* Sbm(char *text, char *pat) {
 int m,n;
 m=strlen(pat);
 n=strlen(text);
 return Sbm2(text,pat,n,m);
}

 


#include <emmintrin.h>
#include <xmmintrin.h>
#define USE_BTR
char* strchrsse(const char *str,char c);
char* strstrabsse(char* text, char* pattern);
//#define REPORT(i) return i;
#ifndef REPORT
#define REPORT(i) {if( report_function(text, i-text, pattern)== SEARCH_STOP) return i;};
#endif

static inline unsigned int hasByteC16(__m128i a0, register __m128i sseic)
{
 return ((_mm_movemask_epi8(_mm_cmpeq_epi8(a0,sseic))  )   ); 

}

static inline unsigned int hasByteC(__m128i a0, __m128i a1, register __m128i sseic)
{
 return ((_mm_movemask_epi8(_mm_cmpeq_epi8(a0,sseic))  )  | \
   (_mm_movemask_epi8(_mm_cmpeq_epi8(a1,sseic)) << 16) \
     ); 
}
#define haszeroByte hasByteC
inline static int strcmpInline(char* str1,char* str2)
{
 while((*str2) && (*str1 == * str2)) {
  str1++;
  str2++;
 }
 if(*str2 == 0) return 0;
 return 1;
}

#    define bsf(x) __builtin_ctz(x)
char* strstrsse(const char* text, const char* pattern)
{
 __m128i * sseiPtr = (__m128i *) text;
 unsigned char * chPtrAligned = (unsigned char*)text;
 __m128i sseiWord0 ;//= *sseiPtr ;
 __m128i sseiWord1 ;//= *sseiPtr ;
 __m128i sseiZero = _mm_set1_epi8(0);
 char chara;
 char charb;
 char charc;
 register __m128i byte16a;
 register __m128i byte16b;
 register __m128i byte16c;
 char* bytePtr =text;
 if(text==NULL)
  return NULL;
 if(text[0] == 0) {
  return pattern[0]?NULL:text;
 }
 if(pattern ==NULL)
  return NULL;
 if(pattern[0] == 0)
  return text;
 if(pattern[1] == 0)
  return strchrsse(text,pattern[0]);
 if(pattern[2] == 0)
  return strstrabsse(text,pattern);
 chara = pattern[0];
 charb = pattern[1];
 charc = pattern[2];
 byte16a = _mm_set1_epi8(chara);
 byte16b = _mm_set1_epi8(charb);
 byte16c = _mm_set1_epi8(charc);
#if 1
 //! the pre-byte that is not aligned.
 {
  int i;
  int j;
  int preBytes = 16 - (((unsigned long long) text) & 15);
  preBytes &= 15;
  if (preBytes == 0)
   goto alignStart;
  chPtrAligned = (unsigned char*)text + preBytes;
  for(j =0;j< preBytes; j++){
   if(text[j] ==0)
    return NULL;
   if(text[j] == chara){
    if(text[j+1] == charb){
     int i=1;
     bytePtr = & text[j];
     while((pattern[i] )&&(bytePtr[i] == pattern[i]))
      i++;
     if(pattern[i] == 0)
      REPORT(bytePtr);
     if(bytePtr[i] == 0)
      return NULL;
    }
   }
  }
  sseiPtr = (__m128i *) chPtrAligned;
 }


#endif
alignStart:
 sseiWord0 = *sseiPtr;
 sseiWord1 = *(sseiPtr+1);
 while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0)
 {
  unsigned int reta ;
searcha:
  reta = hasByteC(sseiWord0,sseiWord1,  byte16a);
  if(reta!=0 ) {
   unsigned int retb ;
   unsigned int retc ;
findouta:  
   retb = hasByteC(sseiWord0,sseiWord1,  byte16b);
   retc = hasByteC(sseiWord0,sseiWord1,  byte16c);
findoutb:
   reta = (reta ) & (retb >> 1);
   reta = (reta ) & (retc >> 2);
   if(reta)
   {
    // have ab
    int i=1;
    char * bytePtr0 = (char*) ( sseiPtr );
    int j;
#ifdef USE_BTR
    while(reta){
     int idx ;
     idx = bsf(reta);
     bytePtr = bytePtr0 + idx ;
     i = 3;
     while((pattern[i] )&&(bytePtr[i] == pattern[i]))
      i++;
     if(pattern[i] == 0)
      REPORT(bytePtr);
     //reta = reta & ( ~(1<<idx));
     __asm__ ( "btr %1, %0"
       :"=r"(reta)
       :"r"(idx),"0"(reta)
       );

    }
#else
    //search completely : version no bsf instruction
    for(j =0;j<8;j++){
     if(reta & 0xff) {
      if(bytePtr0[0] == chara)
       //if(reta & 1)
      {
       i =1;
       bytePtr = bytePtr0 ;
       while((pattern[i] )&&(bytePtr[i] == pattern[i]))
        i++;
       if(pattern[i] == 0)
        REPORT(bytePtr);
      }
      if(bytePtr0[1] == chara)
       //if(reta & 2)
      {
       i =1;
       bytePtr = bytePtr0 + 1;
       while((pattern[i] )&&(bytePtr[i] == pattern[i]))
        i++;
       if(pattern[i] == 0)
        REPORT(bytePtr);
      }
      if(bytePtr0[2] == chara)
       //if(reta & 4)
      {
       i =1;
       bytePtr = bytePtr0 + 2;
       while((pattern[i] )&&(bytePtr[i] == pattern[i]))
        i++;
       if(pattern[i] == 0)
        REPORT(bytePtr);
      }
      if(bytePtr0[3] == chara)
       //if(reta & 8)
      {
       i =1;
       bytePtr = bytePtr0 + 3;
       while((pattern[i] )&&(bytePtr[i] == pattern[i]))
        i++;
       if(pattern[i] == 0)
        REPORT(bytePtr);
      }
     }
     reta = reta >> 4;
     bytePtr0 += 4;
    }
#endif

   }
   // search b
   sseiPtr += 2;
   sseiWord0 = *sseiPtr;
   sseiWord1 = *(sseiPtr+1);

   while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0){
    retc = hasByteC(sseiWord0,sseiWord1,  byte16c);
    if(retc !=0){
     //! this line will decrease the performance, I am a little amazed. if(retc& (3<<30))
     {
      if((*((char*) sseiPtr)) == charb){
       //a|||b000
       char * bytePtr = ((char*) ( sseiPtr )) -1;
       if(bytePtr[0] == chara){
        int i=1;
        while((pattern[i] )&&(bytePtr[i] == pattern[i]))
         i++;
        if(pattern[i] == 0)
         REPORT(bytePtr);
        if(bytePtr[i] == 0)
         return NULL;
       }
      }
#if 1
      if((*((char*) sseiPtr)) == charc){
       //ab||||c000
       char * bytePtr = ((char*) ( sseiPtr )) -2;
       if(bytePtr[0] == chara){
        int i=1;
        while((pattern[i] )&&(bytePtr[i] == pattern[i]))
         i++;
        if(pattern[i] == 0)
         REPORT(bytePtr);
        if(bytePtr[i] == 0)
         return NULL;
       }
      }
     }
#endif
     reta = hasByteC(sseiWord0,sseiWord1,  byte16a);
     if(reta !=0)
     {
      retb = hasByteC(sseiWord0,sseiWord1,  byte16b);
      if(retb !=0)
       goto findoutb;
      else
      {
       if(*(char*) (sseiPtr +2) == charb ){
        char * bytePtr = ((char*) ( sseiPtr +2  )) -1;
        if(bytePtr[0] == chara){
         int i=1;
         while((pattern[i] )&&(bytePtr[i] == pattern[i]))
          i++;
         if(pattern[i] == 0)
          REPORT(bytePtr);
         if(bytePtr[i] == 0)
          return NULL;
        }
       }
       goto nextWord;     
      }
     } 
     else{
      goto nextWord;     
     }
    }
    sseiPtr += 2;
    sseiWord0 = *sseiPtr;
    sseiWord1 = *(sseiPtr+1);
   }
   // search  from (char*)sseiPtr
   char * bytePtr = ((char*) ( sseiPtr )) -1;
   if(bytePtr[0] == chara){
    int i=1;
    while((pattern[i] )&&(bytePtr[i] == pattern[i]))
     i++;
    if(pattern[i] == 0)
     REPORT(bytePtr);
   }
   bytePtr --;
   if(bytePtr[0] == chara){
    int i=1;
    while((pattern[i] )&&(bytePtr[i] == pattern[i]))
     i++;
    if(pattern[i] == 0)
     REPORT(bytePtr);
   }

   goto prePareForEnd;
  }
nextWord:
  sseiPtr += 2;
  sseiWord0 = *sseiPtr;
  sseiWord1 = *(sseiPtr+1);
 }
prePareForEnd:
 {
  unsigned int reta;
  unsigned int retb;
  reta =hasByteC(sseiWord0,sseiWord1,  byte16a);
  retb =hasByteC(sseiWord0,sseiWord1,  byte16b);
  if(((reta<<1) & retb)){
   bytePtr = (char*)sseiPtr;
   while(*bytePtr){
    if(*bytePtr == chara) {
     int i=1;
     while((pattern[i] )&&(bytePtr[i] == pattern[i]))
      i++;
     if(pattern[i] == 0)
      REPORT(bytePtr);
     if(bytePtr[i] == 0)
      return NULL;

    }
    bytePtr++;
   }
  }
 }
 return NULL;
}


char* strstrabsse(char* text, char* pattern)
{
 __m128i * sseiPtr = (__m128i *) text;
 unsigned char * chPtrAligned = (unsigned char*)text;
 __m128i sseiWord0 ;//= *sseiPtr ;
 __m128i sseiWord1 ;//= *sseiPtr ;
 __m128i sseiZero = _mm_set1_epi8(0);
 char chara = pattern[0];
 char charb = pattern[1];
 register __m128i byte16a;
 register __m128i byte16b;
 char* bytePtr =text;
 if(pattern ==NULL)
  return NULL;
 if(pattern[0] == 0)
  return NULL;
 if(pattern[1] == 0)
  return strchrsse(text,pattern[0]);
 byte16a = _mm_set1_epi8(chara);
 byte16b = _mm_set1_epi8(charb);
#if 1
 //! the pre-byte that is not aligned.
 {
  int i;
  int j;
  int preBytes = 16 - (((unsigned long long) text) & 15);
  preBytes &= 15;
  if (preBytes == 0)
   goto alignStart;
  chPtrAligned = (unsigned char*)text + preBytes;
  for(j =0;j< preBytes; j++){
   if(text[j] ==0)
    return NULL;
   if(text[j] == chara){
    if(text[j+1] == charb){
     int i=1;
     bytePtr = & text[j];
     while((pattern[i] )&&(bytePtr[i] == pattern[i]))
      i++;
     if(pattern[i] == 0)
      REPORT(bytePtr);
     if(bytePtr[i] == 0)
      return NULL;
    }
   }
  }
  sseiPtr = (__m128i *) chPtrAligned;
 }


#endif
alignStart:
 sseiWord0 = *sseiPtr;
 sseiWord1 = *(sseiPtr+1);
 while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0)
 {
  unsigned int reta ;
searcha:
  reta = hasByteC(sseiWord0,sseiWord1,  byte16a);
  if(reta!=0 ) {
   unsigned int retb ;
findouta:  
   retb = hasByteC(sseiWord0,sseiWord1,  byte16b);
findoutb:
   reta = (reta ) & (retb >> 1);
   if(reta)
   {
    // have ab
    int i=1;
    char * bytePtr0 = (char*) ( sseiPtr );
    int j;
    //printf("test::%0x,%d\n",reta ,bytePtr0 -text);
    bytePtr = (char*) ( sseiPtr );
    for(j =0;j<8;j++){
     if(reta & 0xff) {
      //if(bytePtr0[0] == chara)
      if(reta & 1)
      {
       bytePtr = bytePtr0 ;
       REPORT(bytePtr);
      }
      //if(bytePtr0[1] == chara)
      if(reta & 2)
      {
       bytePtr = bytePtr0 + 1;
       REPORT(bytePtr);
      }
      //if(bytePtr0[2] == chara)
      if(reta & 4)
      {
       bytePtr = bytePtr0 + 2;
       REPORT(bytePtr);
      }
      //if(bytePtr0[3] == chara)
      if(reta & 8)
      {
       bytePtr = bytePtr0 + 3;
       REPORT(bytePtr);
      }
     }
     reta = reta >> 4;
     bytePtr0 += 4;
    }
   }
   // search b
   sseiPtr += 2;
   sseiWord0 = *sseiPtr;
   sseiWord1 = *(sseiPtr+1);

   while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0){
    retb = hasByteC(sseiWord0,sseiWord1,  byte16b);
    if(retb !=0){
     // findout b
     if((*((char*) sseiPtr)) == charb){
      //b000
      char * bytePtr = ((char*) ( sseiPtr )) -1;
      if(bytePtr[0] == chara){
       int i=1;
       while((pattern[i] )&&(bytePtr[i] == pattern[i]))
        i++;
       if(pattern[i] == 0)
        REPORT(bytePtr);
       if(bytePtr[i] == 0)
        return NULL;
      }

     }
     reta = hasByteC(sseiWord0,sseiWord1,  byte16a);
     if(reta !=0)
      goto findoutb;
     else{
      goto nextWord;     
     }
    }
    sseiPtr += 2;
    sseiWord0 = *sseiPtr;
    sseiWord1 = *(sseiPtr+1);
   }
   // search  from (char*)sseiPtr
   char * bytePtr = ((char*) ( sseiPtr )) -1;
   if(bytePtr[0] == chara){
    int i=1;
    while((pattern[i] )&&(bytePtr[i] == pattern[i])) i++;
    if(pattern[i] == 0) REPORT(bytePtr);
   }

   goto prePareForEnd;
  }
nextWord:
  sseiPtr += 2;
  sseiWord0 = *sseiPtr;
  sseiWord1 = *(sseiPtr+1);
 }
prePareForEnd:
 {
  unsigned int reta;
  unsigned int retb;
  reta =hasByteC(sseiWord0,sseiWord1,  byte16a);
  retb =hasByteC(sseiWord0,sseiWord1,  byte16b);
  if(((reta<<1) & retb)){
   bytePtr = (char*)sseiPtr;
   while(*bytePtr){
    if(*bytePtr == chara) {
     int i=1;
     while((pattern[i] )&&(bytePtr[i] == pattern[i]))
      i++;
     if(pattern[i] == 0)
      REPORT(bytePtr);
     if(bytePtr[i] == 0)
      return NULL;

    }
    bytePtr++;
   }
  }
 }
 return NULL;
}

char* strchrsse(const char *text,char c)
{
 const char *char_ptr=text;
 const __m128i* m128_ptr;
 char pattern[2] ={c,0};
 __m128i byte16c= _mm_set1_epi8(c);
 __m128i sseiZero = _mm_set1_epi8(0);
 __m128i m128word;
 for (char_ptr = text; ((unsigned int)char_ptr
    & (sizeof(__m128) - 1)) != 0;
   ++char_ptr) {
  if (*char_ptr == '\0')
   return NULL;
  if (*char_ptr == c)
   REPORT(char_ptr);
 }

 m128_ptr = (__m128*)char_ptr;


 m128word= *m128_ptr;
 while ((hasByteC16(m128word, sseiZero))==0) {
  if (hasByteC16(m128word, byte16c)  != 0) {
   int i;
   const char *cp = (const char*)(m128_ptr);
   //const char* endcp = cp + 16;
   for(i=0;i<16;i++){
    if(*cp == c)
     REPORT(cp);
    if(*cp==0)
     return NULL;
    cp++;
   }
  }
  m128_ptr++;
  m128word= *m128_ptr;
 }
 {
  const char* cp = (const char*) m128_ptr;
  while(*cp){
    if(*cp == c) REPORT(cp);
    cp++;
  }
 }
 return NULL;
}

#define false 0
#define true 1

int  Like(char *pattern, char escape_character)
{

 char *p = pattern;    // a short for pattern (or processed pattern)
 char *w = pattern;    // a short for wildcard map (or na original pattern, if no escape chars)
 char *v = "aaaaadfdadsfasdfasdfasdfasdfasd";    // a short for the data itself
 uint pattern_len = strlen(pattern);
 int len = strlen(v);
 
 // Escape characters processing
 int i;
 
 for( i = 0; i < pattern_len - 1; i++) {
  if(p[i] == escape_character && (p[i + 1] == escape_character || p[i + 1] == '_' || p[i + 1] == '%')) {
   break;
  }
 }
 // Pattern processing
 int  was_wild = true;    // are we in "after %" mode?
 uint cur_p = 0,  cur_p_beg = 0;  // pattern positions
 uint cur_s = 0,  cur_s_beg = 0;  // source positions

 do {
  while(cur_p < pattern_len && w[cur_p] == '%') {  // first omit all %
   was_wild = true;
   cur_p++;
  }
  cur_s_beg = cur_s;
  cur_p_beg = cur_p;
  do {        // internal loop: try to match a part between %...%
   while(cur_p < pattern_len && cur_s < len &&    // find the first match...
      (v[cur_s] == p[cur_p] || w[cur_p] == '_') &&
      w[cur_p] != '%' ) {
    cur_s++;
    cur_p++;
   }
   if(cur_s < len && ((cur_p < pattern_len && w[cur_p] != '%') || cur_p >= pattern_len)) {  // not matching (loop finished prematurely) - try the next source position
    if(!was_wild)
     return false; // no % up to now => the first non-matching is critical
    cur_p = cur_p_beg;
    cur_s = ++cur_s_beg;   // step forward in the source, rewind the matching pointers
   }
   if(cur_s == len) {   // end of the source
    while(cur_p < pattern_len) {
     if(w[cur_p] != '%')   // Pattern nontrivial yet? No more chances for matching.
      return false;
     cur_p++;
    }
    return true;
   }
  } while(cur_p < pattern_len && w[cur_p] != '%');  // try the next match position
 } while(cur_p < pattern_len && cur_s < len);
 return true;
}

/* char* strstrabxsse(char* text, char* pattern) */
/* { */
/*  __m128i * sseiPtr = (__m128i *) text; */
/*  unsigned char * chPtrAligned = (unsigned char*)text; */
/*  __m128i sseiWord0 ;//= *sseiPtr ; */
/*  __m128i sseiWord1 ;//= *sseiPtr ; */
/*  __m128i sseiZero = _mm_set1_epi8(0); */
/*  char chara = pattern[0]; */
/*  char charb = pattern[1]; */
/*  register __m128i byte16a; */
/*  register __m128i byte16b; */
/*  char* bytePtr =text; */
/*  if(pattern ==NULL) return NULL; */
/*  if(pattern[0] == 0) return NULL; */
/*  if(pattern[1] == 0) return strchrsse(text,pattern[0]);  */
/*  byte16a = _mm_set1_epi8(chara); */
/*  byte16b = _mm_set1_epi8(charb); */
/* #if 1 */
/*  //! the pre-byte that is not aligned. */
/*  { */
/*   int i; */
/*   int j; */
/*   int preBytes = 16 - (((unsigned long long) text) & 15); */
/*   preBytes &= 15; */
/*   if (preBytes == 0) */
/*    goto alignStart; */
/*   chPtrAligned = (unsigned char*)text + preBytes; */
/*   for(j =0;j< preBytes; j++){ */
/*    if(text[j] ==0) */
/*     return NULL; */
/*    if(text[j] == chara){ */
/*     if(text[j+1] == charb){ */
/*      int i=1; */
/*      bytePtr = & text[j]; */
/*      while((pattern[i] )&&(bytePtr[i] == pattern[i])) */
/*       i++; */
/*      if(pattern[i] == 0) */
/*       REPORT(bytePtr); */
/*      if(bytePtr[i] == 0) */
/*       return NULL; */
/*     } */
/*    } */
/*   } */
/*   sseiPtr = (__m128i *) chPtrAligned; */
/*  } */


/* #endif */
/* alignStart: */
/*  sseiWord0 = *sseiPtr; */
/*  sseiWord1 = *(sseiPtr+1); */
/*  while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0)  */
/*  { */
/*   unsigned int reta ; */
/* searcha: */
/*   reta = hasByteC(sseiWord0,sseiWord1,  byte16a); */
/*   if(reta!=0 ) { */
/*    unsigned int retb ; */
/* findouta:   */
/*    retb = hasByteC(sseiWord0,sseiWord1,  byte16b); */
/* findoutb: */
/*    reta = (reta ) & (retb >> 1); */
/*    if(reta) */
/*    { */
/*     // have ab */
/*     int i=1; */
/*     char * bytePtr0 = (char*) ( sseiPtr ); */
/*     int j; */
/*     //printf("test::%0x,%d\n",reta ,bytePtr0 -text); */
/*     bytePtr = (char*) ( sseiPtr ); */
/*     for(j =0;j<8;j++){ */
/*      if(reta & 0xff) { */
/*       if(bytePtr0[0] == chara) */
/*        //if(reta & 1) */
/*       { */
/*        i =1; */
/*        bytePtr = bytePtr0 ; */
/*        while((pattern[i] )&&(bytePtr[i] == pattern[i]))  */
/*         i++; */
/*        if(pattern[i] == 0) */
/*         REPORT(bytePtr); */
/*       } */
/*       if(bytePtr0[1] == chara) */
/*        //if(reta & 2) */
/*       { */
/*        i =1; */
/*        bytePtr = bytePtr0 + 1; */
/*        while((pattern[i] )&&(bytePtr[i] == pattern[i]))  */
/*         i++; */
/*        if(pattern[i] == 0) */
/*         REPORT(bytePtr); */
/*       } */
/*       if(bytePtr0[2] == chara) */
/*        //if(reta & 4) */
/*       { */
/*        i =1; */
/*        bytePtr = bytePtr0 + 2; */
/*        while((pattern[i] )&&(bytePtr[i] == pattern[i])) i++; */
/*        if(pattern[i] == 0) REPORT(bytePtr); */
/*       } */
/*       if(bytePtr0[3] == chara) */
/*        //if(reta & 8) */
/*       { */
/*        i =1; */
/*        bytePtr = bytePtr0 + 3; */
/*        while((pattern[i] )&&(bytePtr[i] == pattern[i]))  */
/*         i++; */
/*        if(pattern[i] == 0) */
/*         REPORT(bytePtr); */
/*       } */
/*      } */
/*      reta = reta >> 4; */
/*      bytePtr0 += 4; */
/*     } */
/*    } */
/*    // search b */
/*    sseiPtr += 2; */
/*    sseiWord0 = *sseiPtr; */
/*    sseiWord1 = *(sseiPtr+1); */

/*    while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0){  */
/*     retb = hasByteC(sseiWord0,sseiWord1,  byte16b); */
/*     if(retb !=0){ */
/*      // findout b */
/*      if((*((char*) sseiPtr)) == charb){ */
/*       //b000 */
/*       char * bytePtr = ((char*) ( sseiPtr )) -1; */
/*       if(bytePtr[0] == chara){ */
/*        int i=1; */
/*        while((pattern[i] )&&(bytePtr[i] == pattern[i])) i++; */
/*        if(pattern[i] == 0)  */
/*         REPORT(bytePtr); */
/*        if(bytePtr[i] == 0) */
/*         return NULL; */
/*       } */

/*      } */
/*      reta = hasByteC(sseiWord0,sseiWord1,  byte16a); */
/*      if(reta !=0)  */
/*       goto findoutb; */
/*      else{ */
/*       goto nextWord;      */
/*      } */
/*     } */
/*     sseiPtr += 2; */
/*     sseiWord0 = *sseiPtr; */
/*     sseiWord1 = *(sseiPtr+1); */
/*    } */
/*    // search  from (char*)sseiPtr */
/*    char * bytePtr = ((char*) ( sseiPtr )) -1; */
/*    if(bytePtr[0] == chara){ */
/*     int i=1; */
/*     while((pattern[i] )&&(bytePtr[i] == pattern[i])) */
/*      i++; */
/*     if(pattern[i] == 0) */
/*      REPORT(bytePtr); */
/*    } */

/*    goto prePareForEnd; */
/*   } */
/* nextWord: */
/*   sseiPtr += 2; */
/*   sseiWord0 = *sseiPtr; */
/*   sseiWord1 = *(sseiPtr+1); */
/*  } */
/* prePareForEnd: */
/*  { */
/*   unsigned int reta; */
/*   unsigned int retb; */
/*   reta =hasByteC(sseiWord0,sseiWord1,  byte16a); */
/*   retb =hasByteC(sseiWord0,sseiWord1,  byte16b); */
/*   if(((reta<<1) & retb)){ */
/*    bytePtr = (char*)sseiPtr; */
/*    while(*bytePtr){ */
/*     if(*bytePtr == chara) { */
/*      int i=1; */
/*      while((pattern[i] )&&(bytePtr[i] == pattern[i])) i++; */
/*      if(pattern[i] == 0) */
/*       REPORT(bytePtr); */
/*      if(bytePtr[i] == 0)  */
/*       return NULL; */

/*     } */
/*     bytePtr++; */
/*    } */
/*   } */
/*  } */
/*  return NULL; */
/* } */

 

#ifndef MAIN_C
#define MAIN_C
#include <stdio.h>
#include <stdlib.h>
#include "rdtsc.h"
size_t strlen_d(const char *str) ;
size_t strlen_l(const char *str);
size_t rb_strlen(const char *str);
char *strstrBerg (const char* phaystack, const char* pneedle);
char *strstrToy (const char* phaystack, const char* pneedle);
char *lstrstr (const char* , const char* );
char *lstrstrsse (const char* , const char* );
char *lstrstr5 (const char* , const char* );
char* strstra(const char *str,char c);
void printstr(char* s)
{
 int i =0;
 printf(":");
 for(i=0;i<10;i++){
  if(s[i] ==0)
   goto ret;
  printf("%c",s[i]);
 }
ret:
 printf("\n");

}
#define LOOPS 1
void test1(int argc,char** argv)
{
 FILE* fp;
 char* text;
 char* textm;
 int len = 1024*1024;
 char pattern[64];
 int testlen[20];
 int i;
 int textlen;
 int patlen;
 double t3;
 char* findp;
 textm = (char*) malloc(len+ 64);
 text = (char*)(((unsigned long long) textm ) & ~63)  +2;
 fp = fopen(argv[1],"r");
 if(fp ==NULL)
  exit(0);
 textlen= fread(text,1,1024*1024,fp);
 text[textlen] = 0;
 fclose(fp);
 for(i=0;i<20;i++)
  testlen[i] =i;
 srand(clock());
 for(patlen = 1;patlen < 20; patlen++){
  int randloops = 0;
  int k;
  printf("*************************************\n");
  printf("%the pattern len is %d \n",patlen);
  randloops = rand() % 5 + 1;
  for(k =0;k < randloops;k++){
   int tmpstart = rand()% textlen; 
   while((tmpstart < textlen )&&(text[tmpstart] != ' ') )
    tmpstart ++;
   tmpstart ++;
   if(tmpstart >= textlen)
    continue;
   for(i=0; i< patlen; i++)
    pattern[i] = text[tmpstart + i];
   pattern[i] =0;
   printf("the pattern is :%s\n",pattern);

   mdtime(0);
   for(i=0;i<LOOPS;i++)
    findp = lstrstrsse(text,pattern);
   t3= mdtime(1);
   printf("lstrsse   time:%15f :%d", t3,findp - text);
   printstr(findp);

   mdtime(0);
   for(i=0;i<LOOPS;i++)
    findp = strstr(text,pattern);
   t3= mdtime(1);
   printf("strstr    time:%15f :%d", t3,findp - text);
   printstr(findp);
   printf("\n");
  }
 }

}
#include "defaultText.h"
int test2( int argc, char** argv)
{

 char text0[] = TEXT;
 char* patterns[] = {"vulture","emente", "MArs","dog","Z","ABG","do","AGB","animals are haunters of the battle field"};    
 char* pattern=patterns[0];

 char text1[] = TEXT1;
 char* patterns1[] = {"vulture","emente", "MArs","dog","Z","ABG","do","AGB","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"};    
 char* pattern1=patterns1[0];

 //char* pattern="dog";
 //char* pattern="Z";
 //char* pattern = "emente";
 //char* pattern = "MArs";
 char* findp;
 char* textm;
 char* text;
 double t3;
 int i,iter;
 int len = 1024*1024;//strlen(text0);
 //int len = strlen(text0);
 textm = (char*) malloc(len+ 64);
 text = (char*)(((unsigned long long) textm ) & ~63)  ;
 
 int n= strlen(text),m=strlen(pattern);
 strcpy(text,text1);
 for (iter=0;iter<9;iter++){
  pattern1 = patterns1[iter];
   n= strlen(text),m=strlen(pattern1);
  printf ("===============sdfasd==================[%s]\n",pattern1);
  printf("\n");

  findp = Sbm2(text,pattern1, n, m);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = Sbm2(text,pattern1, n, m);
  t3= mdtime(1);
  printf("Sbm2         time:%15f :%d, [%s]", t3,findp - text, pattern1);
  printf("\n");

  findp = Sbm(text,pattern1);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = Sbm(text,pattern1);
  t3= mdtime(1);
  printf("Sbm          time:%15f :%d, [%s]", t3,findp - text, pattern1);
  printf("\n");


  findp = strstrsse(text,pattern1);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = strstrsse(text,pattern1);
  t3= mdtime(1);
  printf("strstrsse    time:%15f :%d, [%s]", t3,findp - text, pattern1);
  printf("\n");
 
  findp = strstr(text,pattern1);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = strstr(text,pattern1);
  t3= mdtime(1);
  printf("strstr       time:%15f :%d, [%s]", t3,findp - text,pattern1);
  printf("\n");
 }
 
 /* for(i=0;i<34;i++)  */
 /* { */
 /*  int j=0; */
 /*  for(j=0;j<i;j++)  */
 /*   text[i] = 'a'; */
 /*  strcpy(text+i,text0); */
 /*  mdtime(0); */
 /*  findp = lstrstrsse(text,pattern); */
 /*  t3= mdtime(1); */
 /*  printf("lstrsse   time:%15f :%d, [%s]", t3,findp - text,pattern); */
 /*  printstr(findp); */

 /* } */
 strcpy(text,text0);
 //text = text0 ;
 //for(i=0;i<len;i++){text[i] ='a';}
 //text[i] =0;
  n= strlen(text),m=strlen(pattern);
 printf ("======string:[%d] pattern:[%d]\n",n,m);
 for (iter=0;iter<9;iter++){
  pattern = patterns[iter];
  printf ("=================================[%s]\n",pattern);
  printf("\n");
  findp = lstrstr(text,pattern);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = lstrstr(text,pattern);
  t3= mdtime(1);
  printf("lstrstr      time:%15f :%d. [%s]", t3,findp - text,pattern);
  printstr(findp);

  findp = lstrstrsse(text,pattern);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = lstrstrsse(text,pattern);
  t3= mdtime(1);
  printf("lstrsse      time:%15f :%d, [%s]", t3,findp - text,pattern);
  printstr(findp);
 
  findp = strstr(text,pattern);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = strstr(text,pattern);
  t3= mdtime(1);
  printf("strstr       time:%15f :%d, [%s]", t3,findp - text,pattern);
  printstr(findp);


  findp = strstr_fxxx(text,pattern);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = strstr_fxxx(text,pattern);
  t3= mdtime(1);
  printf("xxxxstrstr   time:%15f :%d, [%s]", t3,findp - text,pattern);
  printf("\n");

  findp = (char *)MYSQLstrstr(text,pattern);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = MYSQLstrstr(text,pattern);
  t3= mdtime(1);
  printf("MYSQLstrstr  time:%15f :%d, [%s]", t3,findp - text,pattern);
  printf("\n");
 
  findp = strstrBerg(text,pattern);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = strstrBerg(text,pattern);
  t3= mdtime(1);
  printf("strstrBerg   time:%15f :%d, [%s]", t3,findp - text, pattern);
  printstr(findp);

  findp = strstrToy(text,pattern);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = strstrToy(text,pattern);
  t3= mdtime(1);
  printf("strstrToy    time:%15f :%d, [%s]", t3,findp - text, pattern);
  printstr(findp);


  findp = Sbm2(text,pattern, n, m);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = Sbm2(text,pattern, n, m);
  t3= mdtime(1);
  printf("Sbm2         time:%15f :%d, [%s]", t3,findp - text, pattern);
  printf("\n");

  findp = Sbm(text,pattern);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = Sbm(text,pattern);
  t3= mdtime(1);
  printf("Sbm          time:%15f :%d, [%s]", t3,findp - text, pattern);
  printf("\n");


  findp = strstrsse(text,pattern);
  mdtime(0);
  for(i=0;i<LOOPS;i++)
   findp = strstrsse(text,pattern);
  t3= mdtime(1);
  printf("strstrsse    time:%15f :%d, [%s]", t3,findp - text, pattern);
  printf("\n");


 }
 
/*result */
/* lstrstr   time:   55682.000000 :4612. [vulture]:vulture do */
/* lstrsse   time:   33407.000000 :4612, [vulture]:vulture do */
/* strstr    time:   23771.000000 :4612, [vulture]:vulture do */
/* Bstrstr   time:   82423.000000 :4612, [vulture]:vulture do */
/* strstrToy time:   80641.000000 :4612, [vulture]:vulture do */

 /* mdtime(0); */
 /* for(i=0;i<LOOPS;i++) */
 /*  len = strlen_d(text); */
 /* t3= mdtime(1); */
 /* printf("strlen_d time:%f :%d, [%s]\n", t3,len, pattern); */

 /* mdtime(0); */
 /* for(i=0;i<LOOPS;i++) */
 /*  len = strlen(text); */
 /* t3= mdtime(1); */
 /* printf("strlen  time:%f :%d, [%s]\n", t3,len, pattern); */

 /* mdtime(0); */
 /* for(i=0;i<LOOPS;i++) */
 /*  len = strlen_l(text); */
 /* t3= mdtime(1); */
 /* printf("strlen_l time:%f :%d, [%s]\n", t3,len,pattern); */

 /* mdtime(0); */
 /* for(i=0;i<LOOPS;i++) */
 /*  len = rb_strlen(text); */
 /* t3= mdtime(1); */
 /* printf("rb_strlen time:%f :%d, [%s]\n", t3,len,pattern); */

 /* mdtime(0); */
 /* for(i=0;i<LOOPS;i++) */
 /*  len = rb_strlenSSE(text); */
 /* t3= mdtime(1); */
 /* printf("rb_strlenSSE time:%f :%d\n", t3,len); */

/* strlen_d time:16929.000000 :4624, [vulture] */
/* strlen  time:34144.000000 :4624, [vulture] */
/* strlen_l time:9559.000000 :4624, [vulture] */
/* rb_strlen time:9284.000000 :4624, [vulture] */

 

}
int main( int argc, char** argv)
{
 test2(argc,argv);
 /* test1(argc,argv); */
 Like("asdf",'q');
 
 return 1;
}
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值