diff options
author | Sam <sam.saffron@gmail.com> | 2018-02-15 15:03:20 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-15 15:03:20 +1100 |
commit | 24131d4a6a97621c1021231c650793ce29c4ed99 (patch) | |
tree | 6e4256c57b7a42990f2cb0976794282d00f5dce6 /actionpack | |
parent | fe6adf43e124f4c9132e5a88a80ebba3f10fd2cb (diff) | |
download | rails-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.
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/lib/action_dispatch/journey/scanner.rb | 15 |
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 |