aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib
diff options
context:
space:
mode:
authorRichard Schneeman <richardschneeman@Richards-MacBook-Air.local>2014-09-27 11:03:18 +0800
committerRichard Schneeman <richardschneeman@Richards-MacBook-Air.local>2014-09-27 13:42:20 +0800
commitdfbcfafd9af046b3e8c79fe7309d31af6f82f9b2 (patch)
tree0d5e886f1cd048a7e3e8eda1448ae4096790836e /railties/lib
parent3f39ac4ee8ea96dbd921b13485e1976c04733889 (diff)
downloadrails-dfbcfafd9af046b3e8c79fe7309d31af6f82f9b2.tar.gz
rails-dfbcfafd9af046b3e8c79fe7309d31af6f82f9b2.tar.bz2
rails-dfbcfafd9af046b3e8c79fe7309d31af6f82f9b2.zip
Move object allocation out of loop
Right now BenchmarkCleaner allocates hundreds of strings on every request with an exception. This patch moves those strings to be generated at boot once and re-used. ## Bench Methods I took a modified form of CodeTriage https://github.com/schneems/codetriage-ko1-test-app/blob/master/perf.rake and ran given rake tasks with and without the patch to BacktraceCleaner. I made an endpoint results in exception ``` def index raise “foo" end ``` The gem `memory_profiler` was used to capture objects allocated for a single request. Then `benchmark/ips` was used to test the speed of the patch. You will see that we use less objects and the code becomes measurably faster with this patch. ## With patch: Memory for one request: ``` Total allocated 7441 Total retained 37 ``` Requests per second: ``` Calculating ------------------------------------- ips 4 i/100ms ------------------------------------------------- ips 43.0 (±4.7%) i/s - 216 in 5.037733s ``` ## Without patch: Memory used for one request: ``` Total allocated 11599 Total retained 35 ``` Requests per second: ``` Calculating ------------------------------------- ips 3 i/100ms ------------------------------------------------- ips 39.4 (±7.6%) i/s - 198 in 5.052783s ``` ## Analysis The patch is faster: ``` (43.0 - 39.4 ) / 39.4 * 100 # => 9 # % ~ speed bump ``` It also allocates less objects: ``` 11599 - 7441 # => 4158 ``` These strings are allocated on __EVERY SINGLE REQUEST__. This patch saves us 4158 objects __PER REQUEST__ with exception. Faster errors == Faster applications
Diffstat (limited to 'railties/lib')
-rw-r--r--railties/lib/rails/backtrace_cleaner.rb13
1 files changed, 9 insertions, 4 deletions
diff --git a/railties/lib/rails/backtrace_cleaner.rb b/railties/lib/rails/backtrace_cleaner.rb
index 8cc8eb1103..5276eb33c9 100644
--- a/railties/lib/rails/backtrace_cleaner.rb
+++ b/railties/lib/rails/backtrace_cleaner.rb
@@ -4,12 +4,16 @@ module Rails
class BacktraceCleaner < ActiveSupport::BacktraceCleaner
APP_DIRS_PATTERN = /^\/?(app|config|lib|test)/
RENDER_TEMPLATE_PATTERN = /:in `_render_template_\w*'/
+ EMPTY_STRING = ''.freeze
+ SLASH = '/'.freeze
+ DOT_SLASH = './'.freeze
def initialize
super
- add_filter { |line| line.sub("#{Rails.root}/", '') }
- add_filter { |line| line.sub(RENDER_TEMPLATE_PATTERN, '') }
- add_filter { |line| line.sub('./', '/') } # for tests
+ @root = "#{Rails.root}/".freeze
+ 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_gem_filters
add_silencer { |line| line !~ APP_DIRS_PATTERN }
@@ -21,7 +25,8 @@ module Rails
return if gems_paths.empty?
gems_regexp = %r{(#{gems_paths.join('|')})/gems/([^/]+)-([\w.]+)/(.*)}
- add_filter { |line| line.sub(gems_regexp, '\2 (\3) \4') }
+ gems_result = '\2 (\3) \4'.freeze
+ add_filter { |line| line.sub(gems_regexp, gems_result) }
end
end
end