提交 f1525dac 编写于 作者: B Ben Hughes

Optimize Journey::Route#score

Scoring routes based on constraints repeated many type conversions that
could be performed in the outer loop.  Determinations of score and
fitness also used Array operations that required allocations.  Against
my benchmark with a large routeset, this reduced object allocations by
over 30x and wall time by over 3x.
上级 47cda2e1
......@@ -92,7 +92,11 @@ def match_route(name, options)
else
routes = non_recursive(cache, options)
hash = routes.group_by { |_, r| r.score(options) }
supplied_keys = options.each_with_object({}) do |(k, v), h|
h[k.to_s] = true if v
end
hash = routes.group_by { |_, r| r.score(supplied_keys) }
hash.keys.sort.reverse_each do |score|
break if score < 0
......
......@@ -96,13 +96,18 @@ def required_keys
required_parts + required_defaults.keys
end
def score(constraints)
def score(supplied_keys)
required_keys = path.required_names
supplied_keys = constraints.map { |k, v| v && k.to_s }.compact
return -1 unless (required_keys - supplied_keys).empty?
required_keys.each do |k|
return -1 unless supplied_keys.include?(k)
end
score = 0
path.names.each do |k|
score += 1 if supplied_keys.include?(k)
end
score = (supplied_keys & path.names).length
score + (required_defaults.length * 2)
end
......
......@@ -96,7 +96,7 @@ def test_score
path = Path::Pattern.from_string "/:controller(/:action(/:id))(.:format)"
generic = Route.build "name", nil, path, constraints, [], {}
knowledge = { id: 20, controller: "pages", action: "show" }
knowledge = { "id" => true, "controller" => true, "action" => true }
routes = [specific, generic]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册