tuned #~= , #= and #startsWith:
These are now 30% faster on a P5 - even without asm support.
--- a/String.st Thu Mar 05 13:38:42 1998 +0100
+++ b/String.st Thu Mar 05 13:43:37 1998 +0100
@@ -937,77 +937,77 @@
int l1, l2;
REGISTER OBJ s = aString;
- char *cp1, *cp2;
+ unsigned char *cp1, *cp2;
OBJ cls;
OBJ myCls;
+ int addrDelta;
if (s == self) {
- RETURN ( true );
+ RETURN ( true );
}
if (! __isNonNilObject(s)) {
- RETURN ( false );
+ RETURN ( false );
}
cls = __qClass(s);
myCls = __qClass(self);
if ((cls == String) || (cls == Symbol) || (cls == myCls)) {
- cp2 = (char *) __stringVal(s);
- l2 = __stringSize(s);
- /*
- * care for instances of subclasses ...
- */
- if (cls != String) {
- int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
-
- cp2 += n;
- l2 -= n;
- }
-
- cp1 = (char *) __stringVal(self);
- l1 = __stringSize(self);
- /*
- * care for instances of subclasses ...
- */
- if (myCls != String) {
- int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(myCls)->c_ninstvars));
-
- cp1 += n;
- l1 -= n;
- }
-
- if (l1 != l2) {
- RETURN ( false );
- }
+ cp2 = (char *) __stringVal(s);
+ l2 = __stringSize(s);
+ /*
+ * care for instances of subclasses ...
+ */
+ if (cls != String) {
+ int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
+
+ cp2 += n;
+ l2 -= n;
+ }
+
+ cp1 = (char *) __stringVal(self);
+ l1 = __stringSize(self);
+ /*
+ * care for instances of subclasses ...
+ */
+ if (myCls != String) {
+ int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(myCls)->c_ninstvars));
+
+ cp1 += n;
+ l1 -= n;
+ }
+
+ if (l1 != l2) {
+ RETURN ( false );
+ }
+#undef FAST_STRNCMP
#ifdef FAST_STRNCMP
- RETURN ( (strncmp(cp1, cp2, l1) == 0) ? true : false );
+ RETURN ( (strncmp(cp1, cp2, l1) == 0) ? true : false );
#else
- while (l1 >= sizeof(INT)) {
- if (((INT *)cp1)[0] != ((INT *)cp2)[0]) {
- RETURN (false);
- }
- l1 -= sizeof(INT);
- cp1 += sizeof(INT);
- cp2 += sizeof(INT);
- }
- if (l1 >= sizeof(short)) {
- if (((short *)cp1)[0] != ((short *)cp2)[0]) {
- RETURN (false);
- }
- l1 -= sizeof(short);
- cp1 += sizeof(short);
- cp2 += sizeof(short);
- }
- while (l1) {
- if (cp1[0] != cp2[0]) {
- RETURN (false);
- }
- l1--;
- cp1++;
- cp2++;
- }
-
- RETURN (true);
+ addrDelta = cp2 - cp1;
+ while (l1 >= sizeof(unsigned INT)) {
+ if (*((unsigned INT *)cp1) != *((unsigned INT *)(cp1+addrDelta))) {
+ RETURN (false);
+ }
+ l1 -= sizeof(unsigned INT);
+ cp1 += sizeof(unsigned INT);
+ }
+ if (l1 >= sizeof(unsigned short)) {
+ if (*((unsigned short *)cp1) != *((unsigned short *)(cp1+addrDelta))) {
+ RETURN (false);
+ }
+ l1 -= sizeof(unsigned short);
+ cp1 += sizeof(unsigned short);
+ }
+ while (l1) {
+ if (*cp1 != *(cp1+addrDelta)) {
+ RETURN (false);
+ }
+ l1--;
+ cp1++;
+ }
+
+ RETURN (true);
#endif
}
%}.
@@ -1180,76 +1180,76 @@
int l1, l2;
REGISTER OBJ s = aString;
- char *cp1, *cp2;
+ unsigned char *cp1, *cp2;
OBJ cls, myCls;
+ int addrDelta;
if (s == self) {
- RETURN ( false );
+ RETURN ( false );
}
if (! __isNonNilObject(s)) {
- RETURN ( true );
+ RETURN ( true );
}
cls = __qClass(s);
myCls = __qClass(self);
if ((cls == String) || (cls == Symbol) || (cls == myCls)) {
- cp1 = (char *) __stringVal(self);
- l1 = __stringSize(self);
- /*
- * care for instances of subclasses ...
- */
- if (myCls != String) {
- int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(myCls)->c_ninstvars));
-
- cp1 += n;
- l1 -= n;
- }
-
- cp2 = (char *) __stringVal(s);
- l2 = __stringSize(s);
- /*
- * care for instances of subclasses ...
- */
- if (cls != String) {
- int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
-
- cp2 += n;
- l2 -= n;
- }
-
- if (l1 != l2) {
- RETURN ( true );
- }
-
+ cp1 = __stringVal(self);
+ l1 = __stringSize(self);
+ /*
+ * care for instances of subclasses ...
+ */
+ if (myCls != String) {
+ int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(myCls)->c_ninstvars));
+
+ cp1 += n;
+ l1 -= n;
+ }
+
+ cp2 = __stringVal(s);
+ l2 = __stringSize(s);
+ /*
+ * care for instances of subclasses ...
+ */
+ if (cls != String) {
+ int n = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
+
+ cp2 += n;
+ l2 -= n;
+ }
+
+ if (l1 != l2) {
+ RETURN ( true );
+ }
+
+#undef FAST_STRNCMP
#ifdef FAST_STRNCMP
- RETURN ( (strncmp(cp1, cp2, l1) == 0) ? false : true );
+ RETURN ( (strncmp(cp1, cp2, l1) == 0) ? false : true );
#else
- while (l1 >= sizeof(INT)) {
- if (((INT *)cp1)[0] != ((INT *)cp2)[0]) {
- RETURN (true);
- }
- l1 -= sizeof(INT);
- cp1 += sizeof(INT);
- cp2 += sizeof(INT);
- }
- if (l1 >= sizeof(short)) {
- if (((short *)cp1)[0] != ((short *)cp2)[0]) {
- RETURN (true);
- }
- l1 -= sizeof(short);
- cp1 += sizeof(short);
- cp2 += sizeof(short);
- }
- while (l1) {
- if (cp1[0] != cp2[0]) {
- RETURN (true);
- }
- l1--;
- cp1++;
- cp2++;
- }
- RETURN (false);
+ addrDelta = cp2 - cp1;
+ while (l1 >= sizeof(unsigned INT)) {
+ if (*((unsigned INT *)cp1) != *((unsigned INT *)(cp1+addrDelta))) {
+ RETURN (true);
+ }
+ l1 -= sizeof(unsigned INT);
+ cp1 += sizeof(unsigned INT);
+ }
+ if (l1 >= sizeof(unsigned short)) {
+ if (*((unsigned short *)cp1) != *((unsigned short *)(cp1+addrDelta))) {
+ RETURN (true);
+ }
+ l1 -= sizeof(unsigned short);
+ cp1 += sizeof(unsigned short);
+ }
+ while (l1) {
+ if (*cp1 != *(cp1+addrDelta)) {
+ RETURN (true);
+ }
+ l1--;
+ cp1++;
+ }
+ RETURN (false);
#endif
}
%}.
@@ -2621,37 +2621,48 @@
REGISTER unsigned char *src1, *src2;
unsigned char c;
- if ((__isString(self) || __isSymbol(self))
- && (__isString(aStringOrChar) || __isSymbol(aStringOrChar))) {
- src1 = __stringVal(self);
- src2 = __stringVal(aStringOrChar);
- if (src1[0] != src2[0]) {
- RETURN ( false );
- }
-
- len1 = __qSize(self);
- len2 = __qSize(aStringOrChar);
- if (len1 < len2) {
- RETURN ( false );
- }
-
- while (c = *src2++) {
- if (c != *src1) {
- RETURN ( false );
- }
- src1++;
- }
- RETURN (true);
+ if (((__qClass(self)==String) || (__qClass(self)==Symbol))
+ && __isNonNilObject(aStringOrChar)
+ && ((__qClass(aStringOrChar)==String) || (__qClass(aStringOrChar)==Symbol))) {
+ src1 = __stringVal(self);
+ src2 = __stringVal(aStringOrChar);
+ if (src1[0] != src2[0]) {
+ RETURN ( false );
+ }
+
+ len1 = __qSize(self);
+ len2 = __qSize(aStringOrChar);
+ if (len1 < len2) {
+ RETURN ( false );
+ }
+
+ while (len2 > (OHDR_SIZE+sizeof(INT))) {
+ if ( *((unsigned INT *)src1) != *((unsigned INT *)src2) ) {
+ RETURN (false);
+ }
+ len2 -= sizeof(INT);
+ src1 += sizeof(INT);
+ src2 += sizeof(INT);
+ }
+
+ while (c = *src2++) {
+ if (c != *src1) {
+ RETURN ( false );
+ }
+ src1++;
+ }
+ RETURN (true);
}
%}.
(aStringOrChar isMemberOf:Character) ifTrue:[
- self size == 0 ifTrue:[^ false].
- ^ (self at:1) == aStringOrChar
+ self size == 0 ifTrue:[^ false].
+ ^ (self at:1) == aStringOrChar
].
^ super startsWith:aStringOrChar
"
- 'hello world' startsWith:'hello'
+ 'hello world' startsWith:'hello'
+ 'hello world' startsWith:'hella'
'hello world' startsWith:'hi'
'hello world' startsWith:$h
'hello world' startsWith:#($h $e $l)
@@ -2661,5 +2672,5 @@
!String class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/String.st,v 1.111 1998-02-07 16:22:07 tz Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/String.st,v 1.112 1998-03-05 12:43:37 cg Exp $'
! !