aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam <sam.saffron@gmail.com>2018-02-15 15:03:20 +1100
committerGitHub <noreply@github.com>2018-02-15 15:03:20 +1100
commit24131d4a6a97621c1021231c650793ce29c4ed99 (patch)
tree6e4256c57b7a42990f2cb0976794282d00f5dce6
parentfe6adf43e124f4c9132e5a88a80ebba3f10fd2cb (diff)
downloadrails-24131d4a6a97621c1021231c650793ce29c4ed99.tar.gz
rails-24131d4a6a97621c1021231c650793ce29c4ed99.tar.bz2
rails-24131d4a6a97621c1021231c650793ce29c4ed99.zip
PERF: dedupe scanned route fragments
Per: https://bugs.ruby-lang.org/issues/13077 String @- will dedupe strings. This takes advantage of this by deduping route fragments that are full of duplication usually. For Discourse: Before: Total allocated: 207574305 bytes (2214916 objects) Total retained: 36470010 bytes (322194 objects) After Total allocated: 207556847 bytes (2214711 objects) Total retained: 36327973 bytes (318627 objects) <- object that GC can not collect So we save 3500 or so RVALUES this way, not the largest saving in the world, but worth it especially for large route files.
-rw-r--r--actionpack/lib/action_dispatch/journey/scanner.rb15
1 files changed, 11 insertions, 4 deletions
diff --git a/actionpack/lib/action_dispatch/journey/scanner.rb b/actionpack/lib/action_dispatch/journey/scanner.rb
index 4ae77903fa..5ed587c1b1 100644
--- a/actionpack/lib/action_dispatch/journey/scanner.rb
+++ b/actionpack/lib/action_dispatch/journey/scanner.rb
@@ -33,6 +33,13 @@ module ActionDispatch
end
private
+
+ # takes advantage of String @- deduping capabilities in Ruby 2.5 upwards
+ # see: https://bugs.ruby-lang.org/issues/13077
+ def dedup_scan(regex)
+ r = @ss.scan(regex)
+ r ? -r : nil
+ end
def scan
case
@@ -47,15 +54,15 @@ module ActionDispatch
[:OR, "|"]
when @ss.skip(/\./)
[:DOT, "."]
- when text = @ss.scan(/:\w+/)
+ when text = dedup_scan(/:\w+/)
[:SYMBOL, text]
- when text = @ss.scan(/\*\w+/)
+ when text = dedup_scan(/\*\w+/)
[:STAR, text]
- when text = @ss.scan(/(?:[\w%\-~!$&'*+,;=@]|\\[:()])+/)
+ when text = dedup_scan(/(?:[\w%\-~!$&'*+,;=@]|\\[:()])+/)
text.tr! "\\", ""
[:LITERAL, text]
# any char
- when text = @ss.scan(/./)
+ when text = dedup_scan(/./)
[:LITERAL, text]
end
end