String.st
branchjv
changeset 18919 dbe023989a90
parent 18907 77e711d30041
parent 18909 b77b871e2795
child 18942 b48824459593
equal deleted inserted replaced
18907:77e711d30041 18919:dbe023989a90
   928 
   928 
   929 %{  /* NOCONTEXT */
   929 %{  /* NOCONTEXT */
   930 #ifdef __SCHTEAM__
   930 #ifdef __SCHTEAM__
   931     if (start.isSmallInteger()
   931     if (start.isSmallInteger()
   932      && aCharacter.isSTCharacter()) {
   932      && aCharacter.isSTCharacter()) {
   933 	int idx1Based = start.intValue();   // st index is 1 based
   933         int idx1Based = start.intValue();   // st index is 1 based
   934 	int jIdx = self.asString().indexOf(aCharacter.charValue(), idx1Based-1);
   934         int jIdx = self.asString().indexOf(aCharacter.charValue(), idx1Based-1);
   935 
   935 
   936 	return context._RETURN( jIdx+1 );    // st index is 1 based
   936         return context._RETURN( jIdx+1 );    // st index is 1 based
   937     }
   937     }
   938 
   938 
   939 #else
   939 #else
   940 # undef __UNROLL_LOOPS__
   940 # undef __UNROLL_LOOPS__
   941 # undef FAST_MEMCHR
   941 # undef FAST_MEMCHR
   949     REGISTER unsigned byteValue;
   949     REGISTER unsigned byteValue;
   950     int last;
   950     int last;
   951     OBJ cls;
   951     OBJ cls;
   952 
   952 
   953     if (__isSmallInteger(start)) {
   953     if (__isSmallInteger(start)) {
   954 	index = __intVal(start);
   954         index = __intVal(start);
   955 	if (index > 0) {
   955         if (index > 0) {
   956 	    if (__isCharacter(aCharacter)) {
   956             if (__isCharacter(aCharacter)) {
   957 		byteValue = __intVal(__characterVal(aCharacter));
   957                 byteValue = __intVal(__characterVal(aCharacter));
   958 		if (byteValue <= 0xFF) {
   958                 if (byteValue <= 0xFF) {
   959 		    last = __stringSize(self);
   959                     last = __stringSize(self);
   960 		    cp = __stringVal(self);
   960                     cp = __stringVal(self);
   961 		    if ((cls = __qClass(self)) != String) {
   961                     if ((cls = __qClass(self)) != String) {
   962 			int numInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   962                         int numInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   963 
   963 
   964 			cp += numInstBytes;
   964                         cp += numInstBytes;
   965 			last -= numInstBytes;
   965                         last -= numInstBytes;
   966 		    }
   966                     }
   967 		    if (index <= last) {
   967                     if (index <= last) {
   968 # ifdef FAST_MEMCHR
   968 # ifdef FAST_MEMCHR
   969 			ncp = (unsigned char *) memchr(cp+index-1, byteValue, last+1-index);
   969                         ncp = (unsigned char *) memchr(cp+index-1, byteValue, last+1-index);
   970 			if (ncp) {
   970                         if (ncp) {
   971 			    RETURN ( __mkSmallInteger(ncp - cp + 1) );
   971                             RETURN ( __mkSmallInteger(ncp - cp + 1) );
   972 			}
   972                         }
   973 # else
   973 # else
   974 #  ifdef __UNROLL_LOOPS__
   974 #  ifdef __UNROLL_LOOPS__
   975 			{
   975                         {
   976 			    int last3 = last-3;
   976                             int last3 = last-3;
   977 
   977 
   978 			    for (; index <= last3; index += 4) {
   978                             for (; index <= last3; index += 4) {
   979 				if (cp[index-1] == byteValue) { RETURN ( __mkSmallInteger(index) ); }
   979                                 if (cp[index-1] == byteValue) { RETURN ( __mkSmallInteger(index) ); }
   980 				if (cp[index-1+1] == byteValue) { RETURN ( __mkSmallInteger(index+1) ); }
   980                                 if (cp[index-1+1] == byteValue) { RETURN ( __mkSmallInteger(index+1) ); }
   981 				if (cp[index-1+2] == byteValue) { RETURN ( __mkSmallInteger(index+2) ); }
   981                                 if (cp[index-1+2] == byteValue) { RETURN ( __mkSmallInteger(index+2) ); }
   982 				if (cp[index-1+3] == byteValue) { RETURN ( __mkSmallInteger(index+3) ); }
   982                                 if (cp[index-1+3] == byteValue) { RETURN ( __mkSmallInteger(index+3) ); }
   983 			    }
   983                             }
   984 			}
   984                         }
   985 #  endif
   985 #  endif
   986 #  ifdef V1
   986 #  ifdef V1
   987 			for (; index <= last; index++) {
   987                         for (; index <= last; index++) {
   988 			    if (cp[index-1] == byteValue) {
   988                             if (cp[index-1] == byteValue) {
   989 				RETURN ( __mkSmallInteger(index) );
   989                                 RETURN ( __mkSmallInteger(index) );
   990 			    }
   990                             }
   991 			}
   991                         }
   992 #  endif
   992 #  endif
   993 #  ifdef V2
   993 #  ifdef V2
   994 			{
   994                         {
   995 			    // see bit twiddling hacks
   995                             // see bit twiddling hacks
   996 #                           define hasZeroByte(v) (((v) - 0x01010101UL) & ~(v) & 0x80808080UL)
   996 #                           define hasZeroByte(v) (((v) - 0x01010101UL) & ~(v) & 0x80808080UL)
   997 #                           define hasByteM(v,m)   hasZeroByte( (v) ^ m)
   997 #                           define hasByteM(v,m)   hasZeroByte( (v) ^ m)
   998 
   998 #   if __POINTER_SIZE__ == 8
   999 			    // the following loop checks four bytes at once
   999 #                           define hasZeroByte8(v) (((v) - 0x0101010101010101ULL) & ~(v) & 0x8080808080808080ULL)
  1000 			    if (((index-1) & 0x3) == 0) {
  1000 #                           define hasByteM8(v,m)   hasZeroByte8( (v) ^ m)
  1001 				int last4 = last-4;
  1001                             // the following loop checks eight bytes at once
  1002 				int m = (~0UL/255 * (byteValue));
  1002                             if (((index-1) & 0x7) == 0) {
  1003 
  1003                                 int last8 = last-8;
  1004 				while (index <= last4) {
  1004                                 INT m = (~0UL/255 * (byteValue));
  1005 				    unsigned int v = *(unsigned int *)(cp+index-1);
  1005 
  1006 
  1006                                 while (index <= last8) {
  1007 				    if (hasByteM(v,m)) break;
  1007                                     unsigned INT v = *(unsigned INT *)(cp+index-1);
  1008 				    index += 4;
  1008 
  1009 				}
  1009                                     if (hasByteM8(v,m)) break;
  1010 			    }
  1010                                     index += 8;
  1011 			    while (index <= last) {
  1011                                 }
  1012 				if (cp[index-1] == byteValue) {
  1012                             }
  1013 				    RETURN ( __mkSmallInteger(index) );
  1013 #   endif
  1014 				}
  1014                             // the following loop checks four bytes at once
  1015 				index++;
  1015                             if (((index-1) & 0x3) == 0) {
  1016 			    }
  1016                                 int last4 = last-4;
  1017 			}
  1017                                 int m = (~0UL/255 * (byteValue));
       
  1018 
       
  1019                                 while (index <= last4) {
       
  1020                                     unsigned int v = *(unsigned int *)(cp+index-1);
       
  1021 
       
  1022                                     if (hasByteM(v,m)) break;
       
  1023                                     index += 4;
       
  1024                                 }
       
  1025                             }
       
  1026                             while (index <= last) {
       
  1027                                 if (cp[index-1] == byteValue) {
       
  1028                                     RETURN ( __mkSmallInteger(index) );
       
  1029                                 }
       
  1030                                 index++;
       
  1031                             }
       
  1032                         }
  1018 #  endif
  1033 #  endif
  1019 # endif
  1034 # endif
  1020 		    }
  1035                     }
  1021 		}
  1036                 }
  1022 	    }
  1037             }
  1023 	    RETURN ( __mkSmallInteger(0) );
  1038             RETURN ( __mkSmallInteger(0) );
  1024 	}
  1039         }
  1025     }
  1040     }
  1026 # undef V2
  1041 # undef V2
  1027 #endif /* not SCHTEAM */
  1042 #endif /* not SCHTEAM */
  1028 %}.
  1043 %}.
  1029     ^ super indexOf:aCharacter startingAt:start
  1044     ^ super indexOf:aCharacter startingAt:start
  1122      |s|
  1137      |s|
  1123      s := String new:1024.
  1138      s := String new:1024.
  1124      s atAllPut:$a.
  1139      s atAllPut:$a.
  1125      s at:512 put:(Character space).
  1140      s at:512 put:(Character space).
  1126      Time millisecondsToRun:[
  1141      Time millisecondsToRun:[
  1127 	1000000 timesRepeat:[ s indexOf:(Character space) ]
  1142         1000000 timesRepeat:[ s indexOf:(Character space) ]
  1128      ]
  1143      ]
  1129 
  1144 
  1130      timing (ms):
  1145      timing (ms):
  1131 	v1: 1763 normal
  1146         v1: 1763 normal
  1132 	    2340 +unroll
  1147             2340 +unroll
  1133 	    3308 memsrch !!
  1148             3308 memsrch !!
  1134 	v2: 1045
  1149         v2: 1045
  1135     "
  1150     "
  1136 
  1151 
  1137     "Modified: / 10-01-2012 / 17:09:34 / cg"
  1152     "Modified: / 10-01-2012 / 17:09:34 / cg"
  1138 !
  1153 !
  1139 
  1154