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

drop array allocations when building paths

```ruby
require 'action_pack'
require 'action_dispatch'
require 'benchmark/ips'

route_set = ActionDispatch::Routing::RouteSet.new
routes = ActionDispatch::Routing::Mapper.new route_set

ObjectSpace::AllocationTracer.setup(%i{path line type})
result = ObjectSpace::AllocationTracer.trace do
  500.times do
    routes.resources :foo
  end
end

sorted = ObjectSpace::AllocationTracer.allocated_count_table.sort_by(&:last)
sorted.each do |k,v|
  next if v == 0
  p k => v
end

__END__

Before:

{:T_SYMBOL=>11}
{:T_REGEXP=>17}
{:T_STRUCT=>6500}
{:T_MATCH=>12004}
{:T_OBJECT=>99009}
{:T_DATA=>100088}
{:T_HASH=>122015}
{:T_STRING=>159637}
{:T_IMEMO=>363134}
{:T_ARRAY=>433056}

After:

{:T_SYMBOL=>11}
{:T_REGEXP=>17}
{:T_STRUCT=>6500}
{:T_MATCH=>12004}
{:T_OBJECT=>91009}
{:T_DATA=>100088}
{:T_HASH=>114013}
{:T_STRING=>159637}
{:T_ARRAY=>321056}
{:T_IMEMO=>351133}
```
This commit is contained in:
Aaron Patterson 2015-08-18 15:57:11 -07:00
parent 4d9475bef9
commit d993cb3629
2 changed files with 8 additions and 8 deletions

View file

@ -41,6 +41,7 @@ module ActionDispatch
def literal?; false; end
def terminal?; false; end
def star?; false; end
def cat?; false; end
end
class Terminal < Node # :nodoc:
@ -117,6 +118,7 @@ module ActionDispatch
end
class Cat < Binary # :nodoc:
def cat?; true; end
def type; :CAT; end
end

View file

@ -187,18 +187,16 @@ module ActionDispatch
def build_path(ast, requirements, anchor)
pattern = Journey::Path::Pattern.new(ast, requirements, JOINED_SEPARATORS, anchor)
builder = Journey::GTG::Builder.new ast
# Get all the symbol nodes followed by literals that are not the
# dummy node.
symbols = ast.grep(Journey::Nodes::Symbol).find_all { |n|
builder.followpos(n).first.literal?
}
symbols = ast.find_all { |n|
n.cat? && n.left.symbol? && n.right.cat? && n.right.left.literal?
}.map(&:left)
# Get all the symbol nodes preceded by literals.
symbols.concat ast.find_all(&:literal?).map { |n|
builder.followpos(n).first
}.find_all(&:symbol?)
symbols.concat ast.find_all { |n|
n.cat? && n.left.literal? && n.right.cat? && n.right.left.symbol?
}.map { |n| n.right.left }
symbols.each { |x|
x.regexp = /(?:#{Regexp.union(x.regexp, '-')})+/