From 9bbd949b1a7bf4039b2d993055531223ccb88079 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Thu, 3 Mar 2016 21:47:09 -0500 Subject: [PATCH] text/flat: FlatText::[] handle statistically common cases first Signed-off-by: Jean Privat --- lib/core/text/flat.nit | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/core/text/flat.nit b/lib/core/text/flat.nit index 2615304..8081ecc 100644 --- a/lib/core/text/flat.nit +++ b/lib/core/text/flat.nit @@ -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 -- 1.7.9.5