diff options
author | Kyrylo Silin <silin@kyrylo.org> | 2019-05-02 02:54:12 +0300 |
---|---|---|
committer | Kyrylo Silin <silin@kyrylo.org> | 2019-05-02 02:54:12 +0300 |
commit | c2747569bb1a16757f6d81f31d74d272f1dafa84 (patch) | |
tree | b17560c8d14bdb7b0395be5d8fe745726332f783 | |
parent | e2c4aa680c2876f3cc8ffd1724c639e0a6a74148 (diff) | |
download | pry-c2747569bb1a16757f6d81f31d74d272f1dafa84.tar.gz |
history: cache @history.count to improve performance
Fixes #2007 (Performance slowdown on entering lines)
By default, when we call `@history.count`, we actually call
`Readline::HISTORY.count`. It turns out this is a very expensive call (probably
`O(n)`). My history file has over 50k lines and calling `count` makes the
problem noticeable by spamming `Enter` as demostrated in the GIF in the issue.
We fix this issue by caching history line count and incrementing/resetting when
needed.
-rw-r--r-- | lib/pry/history.rb | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/lib/pry/history.rb b/lib/pry/history.rb index 17451bd1..7200a69d 100644 --- a/lib/pry/history.rb +++ b/lib/pry/history.rb @@ -21,8 +21,12 @@ class Pry # @return [Fixnum] Number of lines in history when Pry first loaded. attr_reader :original_lines + # @return [Integer] total number of lines, including original lines + attr_reader :history_line_count + def initialize(options = {}) @history = options[:history] || [] + @history_line_count = @history.count @file_path = options[:file_path] @original_lines = 0 @loader = method(:read_from_file) @@ -37,6 +41,7 @@ class Pry @history << line.chomp @original_lines += 1 + @history_line_count += 1 end end @@ -55,6 +60,7 @@ class Pry return line if line == last_line @history << line + @history_line_count += 1 @saver.call(line) if !should_ignore?(line) && Pry.config.history_save line @@ -65,17 +71,13 @@ class Pry # history file. def clear @history.clear + @history_line_count = 0 @original_lines = 0 end - # @return [Fixnum] The number of lines in history. - def history_line_count - @history.count - end - # @return [Fixnum] The number of lines in history from just this session. def session_line_count - @history.count - @original_lines + @history_line_count - @original_lines end # Return an Array containing all stored history. |