Merge: Performance update on Buffer
authorJean Privat <jean@pryen.org>
Thu, 20 Aug 2015 15:04:44 +0000 (11:04 -0400)
committerJean Privat <jean@pryen.org>
Thu, 20 Aug 2015 15:04:44 +0000 (11:04 -0400)
This PR is essentially the same as #1632, which has been invalidated by some black magic.

This PR heavily improves the performance on FlatBuffer by introducing cache mechanisms on indexed access.

This is possible through removal of byte-level manipulation on Buffers and re-introduction of a constant-time length attribute on Buffer.

nitmd is now practicable again and should no longer take too much time when running benches.

This PR still depends on #1628, and as such will not pass no tests as long as it is not integrated

Pull-Request: #1644

1  2 
lib/standard/text/abstract_text.nit

@@@ -240,6 -240,89 +240,6 @@@ abstract class Tex
                return b.to_s
        end
  
 -      # Is `self` a well-formed Integer (i.e. parsable via `to_i`)
 -      #
 -      #     assert "123".is_int
 -      #     assert "0b1011".is_int
 -      #     assert not "0x_".is_int
 -      #     assert not "0xGE".is_int
 -      fun is_int: Bool do
 -              var s = remove_all('_')
 -              var pos = 0
 -              while s[pos] == '-' do
 -                      pos += 1
 -              end
 -              s = s.substring_from(pos)
 -              var rets = s.strip_numhead
 -              if rets == "" then return false
 -              var hd = get_numhead
 -              if hd == "0x" or hd == "0X" then return rets.is_hex
 -              if hd == "0b" or hd == "0B" then return rets.is_bin
 -              if hd == "0o" or hd == "0O" then return rets.is_oct
 -              return hd.is_dec
 -      end
 -
 -      # Removes the numeric head of `self` if present
 -      #
 -      #     intrude import standard::text::abstract_text
 -      #     assert "0xFFEF".strip_numhead  == "FFEF"
 -      #     assert "0o7364".strip_numhead  == "7364"
 -      #     assert "0b01001".strip_numhead == "01001"
 -      #     assert "98".strip_numhead      == "98"
 -      private fun strip_numhead: Text do
 -              if get_numhead != "" then return substring_from(2)
 -              return self
 -      end
 -
 -      # Gets the numeric head of `self` if present
 -      # Returns "" otherwise
 -      #
 -      #     intrude import standard::text::abstract_text
 -      #     assert "0xFEFF".get_numhead  == "0x"
 -      #     assert "0b01001".get_numhead == "0b"
 -      #     assert "0o872".get_numhead   == "0o"
 -      #     assert "98".get_numhead      == ""
 -      private fun get_numhead: Text do
 -              if self.length < 2 then return ""
 -              var c = self[0]
 -              if c != '0' then return ""
 -              c = self[1]
 -              if c == 'x' or c == 'b' or c == 'o' or
 -                 c == 'X' or c == 'B' or c == 'O' then return substring(0, 2)
 -              return ""
 -      end
 -
 -      # Removes the numeric extension if present
 -      #
 -      #     intrude import standard::text::abstract_text
 -      #     assert "0xFEFFu8".strip_numext  == "0xFEFF"
 -      #     assert "0b01001u8".strip_numext == "0b01001"
 -      #     assert "0o872u8".strip_numext   == "0o872"
 -      #     assert "98".strip_numext        == "98"
 -      private fun strip_numext: Text do
 -              var ext = get_numext
 -              if ext != "" then return substring(0, length - ext.length)
 -              return self
 -      end
 -
 -      # Gets the numeric extension (i/u 8/16/32) in `self` is present
 -      # Returns "" otherwise
 -      #
 -      #     intrude import standard::text::abstract_text
 -      #     assert "0xFEFFu8".get_numext  == "u8"
 -      #     assert "0b01001u8".get_numext == "u8"
 -      #     assert "0o872u8".get_numext   == "u8"
 -      #     assert "98".get_numext        == ""
 -      private fun get_numext: Text do
 -              var len = self.length
 -              var max = if self.length < 3 then self.length else 3
 -              for i in [1 .. max] do
 -                      var c = self[len - i]
 -                      if c == 'i' or c == 'u' then return substring_from(len - i)
 -              end
 -              return ""
 -      end
 -
        # Returns `self` as the corresponding integer
        #
        #     assert "123".to_i        == 123
        #     assert "--12".to_i       == 12
        #
        # REQUIRE: `self`.`is_int`
 -      fun to_i: Int
 -      do
 -              assert self.is_int
 -              var s = remove_all('_')
 -              var val = 0
 -              var neg = false
 -              var pos = 0
 -              while s[pos] == '-' do
 -                      neg = not neg
 -                      pos += 1
 -              end
 -              s = s.substring_from(pos)
 -              if s.length >= 2 then
 -                      var s1 = s[1]
 -                      if s1 == 'x' or s1 == 'X' then
 -                              val = s.substring_from(2).to_hex
 -                      else if s1 == 'o' or s1 == 'O' then
 -                              val = s.substring_from(2).to_oct
 -                      else if s1 == 'b' or s1 == 'B' then
 -                              val = s.substring_from(2).to_bin
 -                      else if s1.is_numeric then
 -                              val = s.to_dec
 -                      end
 -              else
 -                      val = s.to_dec
 -              end
 -              return if neg then -val else val
 -      end
 -
 -      # Is `self` a valid integer ?
 -      #
 -      #     assert "0xFE46u8".is_num
 -      #     assert "0b0100".is_num
 -      #     assert "0o645".is_num
 -      #     assert "897u8".is_num
 -      fun is_num: Bool do
 -              var prefix = get_numhead
 -              var s = strip_numhead.strip_numext.remove_all('_')
 -              if prefix != "" then
 -                      var c = prefix[1]
 -                      if c == 'x' or c == 'X' then return s.is_hex
 -                      if c == 'o' or c == 'O' then return s.is_oct
 -                      if c == 'b' or c == 'B' then return s.is_bin
 -              end
 -              return s.is_dec
 -      end
 -
 -      # Is `self` is a properly formatted integer, returns the corresponding value
 -      #
 -      #     assert "0xFEu8".to_num  == 254u8
 -      #     assert "0b10_10".to_num != 10u8
 -      fun to_num: nullable Numeric do
 -              if not is_num then return null
 -              var s = remove_all('_')
 -              var ext = s.get_numext
 -              var trunk = s.strip_numext
 -              if trunk.strip_numhead == "" then return null
 -              var trval = trunk.to_i
 -              if ext == "u8" then
 -                      return trval.to_b
 -              else if ext == "" then
 -                      return trval
 -              else
 -                      return null
 -              end
 -      end
 +      fun to_i: Int is abstract
  
        # If `self` contains a float, return the corresponding float
        #
@@@ -1353,10 -1501,6 +1353,6 @@@ abstract class Buffe
        # In Buffers, the internal sequence of character is mutable
        # Thus, `chars` can be used to modify the buffer.
        redef fun chars: Sequence[Char] is abstract
-       # In Buffers, the internal sequence of bytes is mutable
-       # Thus, `bytes` can be used to modify the buffer.
-       redef fun bytes: Sequence[Byte] is abstract
  end
  
  # View for chars on Buffer objects, extends Sequence
@@@ -1373,7 -1517,6 +1369,6 @@@ en
  # for mutation operations
  private abstract class BufferByteView
        super StringByteView
-       super Sequence[Byte]
  
        redef type SELFTYPE: Buffer
  end