Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

_rl_adjust_point: performance fix with large point

_rl_adjust_point() takes a long time when inserting text. If point
argument is a large value, performance is poor. In this case, counting
byte size from tail of the string will improve performance. Resetting
encoding instead of String#dup will give a small improvement.

Tested-by: Mark Somerville <mark@scottishclimbs.com> [F16, MRI 1.8.7, MRI 1.9.3]
Signed-off-by: Mark Somerville <mark@scottishclimbs.com>
  • Loading branch information...
commit 671713d445fffffa06776d3b6ef089e7e4cee67e 1 parent d1aaa2d
Hiroshi Shirosaki shirosaki authored Spakman committed
26 bench/_rl_adjust_point.rb
View
@@ -0,0 +1,26 @@
+$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib/"
+require 'rbreadline'
+require 'benchmark'
+
+N = 100_000
+
+Benchmark.bmbm do |x|
+ x.report do
+ N.times { RbReadline._rl_adjust_point("a", 0) }
+ end
+ x.report do
+ N.times { RbReadline._rl_adjust_point("a", 1) }
+ end
+ x.report do
+ N.times { RbReadline._rl_adjust_point("aaaaaaaaaaaaaaaaaaaaa", 0) }
+ end
+ x.report do
+ N.times { RbReadline._rl_adjust_point("aaaaaaaaaaaaaaaaaaaaa", 40) }
+ end
+ x.report do
+ N.times { RbReadline._rl_adjust_point("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0) }
+ end
+ x.report do
+ N.times { RbReadline._rl_adjust_point("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 40) }
+ end
+end
25 lib/rbreadline.rb
View
@@ -8524,12 +8524,27 @@ def _rl_adjust_point(string, point)
i += 1
end
when 'X'
- str = string.dup.force_encoding(@encoding_name)
- i, len = 0, str.length
- while (pos < point && i < len)
- pos += str[i].bytesize
- i += 1
+ enc = string.encoding
+ str = string.force_encoding(@encoding_name)
+ len = str.length
+ if point <= length / 2
+ # count byte size from head
+ i = 0
+ while (pos < point && i < len)
+ pos += str[i].bytesize
+ i += 1
+ end
+ else
+ # count byte size from tail
+ pos = str.bytesize
+ i = len - 1
+ while (pos > point && i >= 0)
+ pos -= str[i].bytesize
+ i -= 1
+ end
+ pos += str[i + 1].bytesize if pos < point
end
+ string.force_encoding(enc)
else
pos = point
end
14 test/test_rbreadline.rb
View
@@ -6,4 +6,18 @@ def test_versions
assert_equal('5.2', RbReadline::RL_LIBRARY_VERSION)
assert_equal(0x0502, RbReadline::RL_READLINE_VERSION)
end
+
+ def test_rl_adjust_point
+ encoding_name = RbReadline.instance_variable_get(:@encoding_name)
+ RbReadline.instance_variable_set(:@encoding_name, Encoding.find('UTF-8'))
+
+ assert_equal(0, RbReadline._rl_adjust_point("a".force_encoding('ASCII-8BIT'), 0))
+ assert_equal(0, RbReadline._rl_adjust_point("a".force_encoding('ASCII-8BIT'), 1))
+ assert_equal(0, RbReadline._rl_adjust_point(("a" * 40).force_encoding('ASCII-8BIT'), 0))
+ assert_equal(0, RbReadline._rl_adjust_point(("a" * 40).force_encoding('ASCII-8BIT'), 40))
+ assert_equal(2, RbReadline._rl_adjust_point(("\u3042" * 10).force_encoding('ASCII-8BIT'), 1))
+ assert_equal(1, RbReadline._rl_adjust_point(("\u3042" * 15).force_encoding('ASCII-8BIT'), 38))
+ ensure
+ RbReadline.instance_variable_set(:@encoding_name, encoding_name)
+ end if defined?(Encoding)
end
Please sign in to comment.
Something went wrong with that request. Please try again.