From 24131d4a6a97621c1021231c650793ce29c4ed99 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 15 Feb 2018 15:03:20 +1100 Subject: 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. --- actionpack/lib/action_dispatch/journey/scanner.rb | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'actionpack') 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 -- cgit v1.2.3