text/flat: FlatText::[] handle statistically common cases first
authorJean Privat <jean@pryen.org>
Fri, 4 Mar 2016 02:47:09 +0000 (21:47 -0500)
committerJean Privat <jean@pryen.org>
Fri, 4 Mar 2016 02:59:15 +0000 (21:59 -0500)
Signed-off-by: Jean Privat <jean@pryen.org>

lib/core/text/flat.nit

index 2615304..8081ecc 100644 (file)
@@ -296,7 +296,49 @@ redef class FlatText
        end
 
        redef fun [](index) do
-               assert index >= 0 and index < _length
+               var len = _length
+
+               # Statistically:
+               # * ~70% want the next char
+               # * ~23% want the previous
+               # * ~7% want the same char
+               #
+               # So it makes sense to shortcut early. And early is here.
+               var dpos = index - _position
+               var b = _bytepos
+               if dpos == 1 and index < len - 1 then
+                       var its = _items
+                       var c = its[b]
+                       if c & 0x80u8 == 0x00u8 then
+                               # We want the next, and current is easy.
+                               # So next is easy to find!
+                               b += 1
+                               _position = index
+                               _bytepos = b
+                               # The rest will be done by `dpos==0` bellow.
+                               dpos = 0
+                       end
+               else if dpos == -1 and index > 1 then
+                       var its = _items
+                       var c = its[b-1]
+                       if c & 0x80u8 == 0x00u8 then
+                               # We want the previous, and it is easy.
+                               b -= 1
+                               dpos = 0
+                               _position = index
+                               _bytepos = b
+                               return c.ascii
+                       end
+               end
+               if dpos == 0 then
+                       # We know what we want (+0 or +1) just get it now!
+                       var its = _items
+                       var c = its[b]
+                       if c & 0x80u8 == 0x00u8 then return c.ascii
+                       return items.char_at(b)
+               end
+
+               assert index >= 0 and index < len
                return fetch_char_at(index)
        end