#TUNING by cg
authorClaus Gittinger <cg@exept.de>
Tue, 26 Mar 2019 11:36:14 +0100
changeset 23974 2601c14688d8
parent 23973 868df53eb2f5
child 23975 7133afff1d2f
#TUNING by cg class: TwoByteString added: #from:to:put:
TwoByteString.st
--- a/TwoByteString.st	Mon Mar 25 16:43:41 2019 +0100
+++ b/TwoByteString.st	Tue Mar 26 11:36:14 2019 +0100
@@ -118,6 +118,103 @@
 
 !TwoByteString methodsFor:'filling and replacing'!
 
+from:start to:stop put:aCharacter
+    "fill part of the receiver with aCharacter.
+     - reimplemented here for speed"
+
+%{  /* NOCONTEXT */
+
+    REGISTER unsigned short *dstp;
+    REGISTER int count, charValue;
+    int len, index1, index2;
+    OBJ cls;
+    
+    // fprintf(stderr, "fill16...\n");
+    if (__isCharacter(aCharacter)
+     && __bothSmallInteger(start, stop)) {
+        len = __twoByteStringSize(self);
+        index1 = __intVal(start);
+        index2 = __intVal(stop);
+
+        dstp = __twoByteStringVal(self) + index1 - 1;
+        if ((cls = __qClass(self)) != @global(Unicode16String)) {
+            int nInst;
+
+            nInst = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
+            dstp += nInst;
+            len -= nInst;
+        }
+
+        charValue = __intVal(__characterVal(aCharacter));
+        if (((unsigned)charValue <= 0xFFFF)
+         && (index1 <= index2)
+         && (index1 > 0)) {
+            if (index2 <= len) {
+                count = index2 - index1 + 1;
+
+#if (__POINTER_SIZE__ == 8)
+                {
+                    INT v4;
+
+                    v4 = (charValue << 16) | charValue;
+                    v4 = (v4 << 32) | v4;
+
+                    /* fill unaligned part */
+                    while ((count > 0) && (((unsigned INT)dstp & 7) != 0)) {
+                        *dstp++ = charValue;
+                        count--;
+                    }
+
+                    /* fill aligned part */
+                    while (count >= 4) {
+                        ((unsigned INT *)dstp)[0] = v4;
+                        dstp += 4;
+                        count -= 4;
+                    }
+
+                    /* fill rest */
+                    while (count > 0) {
+                        *dstp++ = charValue;
+                        count--;
+                    }
+                    RETURN (self);
+                }
+#endif /* 64bit */
+
+                while (count >= 8) {
+                    dstp[0] = dstp[1] = dstp[2] = dstp[3] =
+                    dstp[4] = dstp[5] = dstp[6] = dstp[7] = charValue;
+                    dstp += 8;
+                    count -= 8;
+                }
+                while (count--) {
+                    *dstp++ = charValue;
+                }
+                RETURN (self);
+            }
+        }
+    }
+%}.
+    "
+     fall back in case of non-integer index or out-of-bound index/value;
+     will eventually lead to an out-of-bound signal raise
+    "
+    ^ super from:start to:stop put:aCharacter
+
+    "
+     (Unicode16String new:10) from:1 to:10 put:$a
+     (Unicode16String new:20) from:10 to:20 put:$b
+     (Unicode16String new:20) from:1 to:10 put:$c
+     (Unicode16String new:20) from:1 to:10 put:$c 
+     (Unicode16String new:100) from:2 to:99 put:$c 
+
+     (Unicode16String new:10) from:0 to:9 put:$a
+     (Unicode16String new:10) from:1 to:11 put:$a
+    "
+
+    "Created: / 26-03-2019 / 11:20:14 / Claus Gittinger"
+!
+
 replaceFrom:start to:stop with:aString startingAt:repStart
     "replace the characters starting at index start, anInteger and ending
      at stop, anInteger with characters from aString starting at repStart.