1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Avoid string allocations in BacktraceCleaner

Our backtraces tend to be fairly large so this operates over quite a few
strings.

Previously, each filter would call `String#sub`, which always returns a
new string object, and uses a new string buffer any time it modifies the
string.

String#slice allows Ruby to share the same internal string buffer, which
should be faster and use less memory. In cases where changes aren't
necessary we can also reuse the same string object.

This should not change behaviour except for the last filter which
changes from sub(/\.\//, "") to sub(/\A\.\//, ""), which I think was the
original intention.
This commit is contained in:
John Hawthorn 2019-04-15 15:01:12 -07:00
parent 4f5c63296e
commit 9a959a0c45

View file

@ -4,18 +4,25 @@ require "active_support/backtrace_cleaner"
module Rails
class BacktraceCleaner < ActiveSupport::BacktraceCleaner
APP_DIRS_PATTERN = /^\/?(app|config|lib|test|\(\w*\))/
APP_DIRS_PATTERN = /\A\/?(?:app|config|lib|test|\(\w*\))/
RENDER_TEMPLATE_PATTERN = /:in `.*_\w+_{2,3}\d+_\d+'/
EMPTY_STRING = ""
SLASH = "/"
DOT_SLASH = "./"
def initialize
super
@root = "#{Rails.root}/"
add_filter { |line| line.sub(@root, EMPTY_STRING) }
add_filter { |line| line.sub(RENDER_TEMPLATE_PATTERN, EMPTY_STRING) }
add_filter { |line| line.sub(DOT_SLASH, SLASH) } # for tests
add_filter do |line|
line.start_with?(@root) ? line.from(@root.size) : line
end
add_filter do |line|
if RENDER_TEMPLATE_PATTERN.match?(line)
line.sub(RENDER_TEMPLATE_PATTERN, "")
else
line
end
end
add_filter do |line|
line.start_with?("./") ? line.from(1) : line
end
add_silencer { |line| !APP_DIRS_PATTERN.match?(line) }
end
end