diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index abb5964fd942a..7bbc962d9104f 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Cache recognized routes. #1233 [skaes@web.de] + * Cache several controller variables that are expensive to calculate. #1229 [skaes@web.de] * The session class backing CGI::Session::ActiveRecordStore may be replaced with any class that duck-types with a subset of Active Record. See docs for details. #1238 [skaes@web.de] diff --git a/actionpack/lib/action_controller/routing.rb b/actionpack/lib/action_controller/routing.rb index 3771d3feade02..6a0988b7549dd 100644 --- a/actionpack/lib/action_controller/routing.rb +++ b/actionpack/lib/action_controller/routing.rb @@ -416,21 +416,33 @@ def write_generation return (method_sources << code) end + @@recognized_route_cache = {} def recognize(request) - string_path = request.path - string_path.chomp! if string_path[0] == ?/ - path = string_path.split '/' - path.shift - - hash = recognize_path(path) - recognition_failed(request) unless hash && hash['controller'] - - controller = hash['controller'] - hash['controller'] = controller.controller_path - request.path_parameters = hash - controller.new + if recognized = @@recognized_route_cache[request.path] + controller, options = recognized + request.path_parameters = options + controller + else + string_path = request.path + string_path.chomp! if string_path[0] == ?/ + path = string_path.split '/' + path.shift + + hash = recognize_path(path) + recognition_failed(request) unless hash && hash['controller'] + + controller = hash['controller'] + hash['controller'] = controller.controller_path + request.path_parameters = hash + @@recognized_route_cache[request.path] = [controller, hash] + controller.new + end end alias :recognize! :recognize + + def clear_recognized_route_cache! + @@recognized_route_cache.clear + end def recognition_failed(request) raise ActionController::RoutingError, "Recognition failed for #{request.path.inspect}"