aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/journey
Commit message (Collapse)AuthorAgeFilesLines
* pass pass the mapping object down the add_route stackAaron Patterson2015-08-141-2/+12
| | | | | then we can let the mapping object derive stuff that the Route object needs.
* pull up path parsingAaron Patterson2015-08-141-0/+4
| | | | | `add_route` needs the AST, so rather than shove it in a hash and delete later, lets move parsing up the stack so we can pass down later
* use predicate methods instead of hard coding verb stringsAaron Patterson2015-08-141-1/+1
| | | | | also change the feeler to subclass AD::Request so that it has all the methods that Request has
* remove hard coded regular expressionAaron Patterson2015-08-142-1/+5
|
* remove StrexpAaron Patterson2015-08-133-34/+11
| | | | | This was a useless object. We can just directly construct a Path::Pattern object without a Strexp object.
* pass anchor directly to `Pattern`Aaron Patterson2015-08-132-8/+7
| | | | | the caller already has it, there is no reason to pack it in to an object and just throw that object away.
* Array#any? is slower and not the inverse of Array#empty?Jean Boussier2015-07-301-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ``` empty_array = [] small_array = [1] * 30 bigger_array = [1] * 300 Benchmark.ips do |x| x.report('empty !empty?') { !empty_array.empty? } x.report('small !empty?') { !small_array.empty? } x.report('bigger !empty?') { !bigger_array.empty? } x.report('empty any?') { empty_array.any? } x.report('small any?') { small_array.any? } x.report('bigger any?') { bigger_array.any? } end ``` ``` Calculating ------------------------------------- empty !empty? 132.059k i/100ms small !empty? 133.974k i/100ms bigger !empty? 133.848k i/100ms empty any? 106.924k i/100ms small any? 85.525k i/100ms bigger any? 86.663k i/100ms ------------------------------------------------- empty !empty? 8.522M (± 7.9%) i/s - 42.391M small !empty? 8.501M (± 8.5%) i/s - 42.202M bigger !empty? 8.434M (± 8.6%) i/s - 41.894M empty any? 4.161M (± 8.3%) i/s - 20.743M small any? 2.654M (± 5.2%) i/s - 13.256M bigger any? 2.642M (± 6.4%) i/s - 13.173M ``` Ref: https://github.com/rails/rails/pull/21057#discussion_r35902468
* Use delete_if instead of each; delete(key)schneems2015-07-301-3/+2
| | | | | | | | | | | | | It is slightly faster: ``` Calculating ------------------------------------- each; delete 35.166k i/100ms delete_if 36.416k i/100ms ------------------------------------------------- each; delete 478.026k (± 8.5%) i/s - 2.391M delete_if 485.123k (± 7.9%) i/s - 2.440M ```
* Remove (another) array allocationschneems2015-07-301-5/+14
| | | | | | We don't always need an array when generating a url with the formatter. We can be lazy about allocating the `missing_keys` array. This saves us: 35,606 bytes and 889 objects per request
* Remove array allocationschneems2015-07-301-2/+2
| | | | | | THe only reason we were allocating an array is to get the "missing_keys" variable in scope of the error message generator. Guess what? Arrays kinda take up a lot of memory, so by replacing that with a nil, we save: 35,303 bytes and 886 objects per request
* Avoid calling to_s on nil in journey/formatterschneems2015-07-301-2/+2
| | | | | | | | When `defaults[key]` in `generate` in the journey formatter is called, it often returns a `nil` when we call `to_s` on a nil, it allocates an empty string. We can skip this check when the default value is nil. This change buys us 35,431 bytes of memory and 887 fewer objects per request. Thanks to @matthewd for help with the readability
* Speed up journey missing_keysschneems2015-07-291-3/+15
| | | | | | | | Most routes have a `route.path.requirements[key]` of `/[-_.a-zA-Z0-9]+\/[-_.a-zA-Z0-9]+/` yet every time this method is called a new regex is generated on the fly with `/\A#{DEFAULT_INPUT}\Z/`. OBJECT ALLOCATIONS BLERG! This change uses a special module that implements `===` so it can be used in a case statement to pull out the default input. When this happens, we use a pre-generated regex. This change buys us 1,643,465 bytes of memory and 7,990 fewer objects per request.
* Speed up journey extract_parameterized_partsschneems2015-07-291-2/+3
| | | | | | | | Micro optimization: `reverse.drop_while` is slower than `reverse_each.drop_while`. This doesn't save any object allocations. Second, `keys_to_keep` is typically a very small array. The operation `parameterized_parts.keys - keys_to_keep` actually allocates two arrays. It is quicker (I benchmarked) to iterate over each and check inclusion in array manually. This change buys us 1774 fewer objects per request
* Freeze string literals when not mutated.schneems2015-07-192-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I wrote a utility that helps find areas where you could optimize your program using a frozen string instead of a string literal, it's called [let_it_go](https://github.com/schneems/let_it_go). After going through the output and adding `.freeze` I was able to eliminate the creation of 1,114 string objects on EVERY request to [codetriage](codetriage.com). How does this impact execution? To look at memory: ```ruby require 'get_process_mem' mem = GetProcessMem.new GC.start GC.disable 1_114.times { " " } before = mem.mb after = mem.mb GC.enable puts "Diff: #{after - before} mb" ``` Creating 1,114 string objects results in `Diff: 0.03125 mb` of RAM allocated on every request. Or 1mb every 32 requests. To look at raw speed: ```ruby require 'benchmark/ips' number_of_objects_reduced = 1_114 Benchmark.ips do |x| x.report("freeze") { number_of_objects_reduced.times { " ".freeze } } x.report("no-freeze") { number_of_objects_reduced.times { " " } } end ``` We get the results ``` Calculating ------------------------------------- freeze 1.428k i/100ms no-freeze 609.000 i/100ms ------------------------------------------------- freeze 14.363k (± 8.5%) i/s - 71.400k no-freeze 6.084k (± 8.1%) i/s - 30.450k ``` Now we can do some maths: ```ruby ips = 6_226k # iterations / 1 second call_time_before = 1.0 / ips # seconds per iteration ips = 15_254 # iterations / 1 second call_time_after = 1.0 / ips # seconds per iteration diff = call_time_before - call_time_after number_of_objects_reduced * diff * 100 # => 0.4530373333993266 miliseconds saved per request ``` So we're shaving off 1 second of execution time for every 220 requests. Is this going to be an insane speed boost to any Rails app: nope. Should we merge it: yep. p.s. If you know of a method call that doesn't modify a string input such as [String#gsub](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37) please [give me a pull request to the appropriate file](https://github.com/schneems/let_it_go/blob/b0e2da69f0cca87ab581022baa43291cdf48638c/lib/let_it_go/core_ext/string.rb#L37), or open an issue in LetItGo so we can track and freeze more strings. Keep those strings Frozen ![](https://www.dropbox.com/s/z4dj9fdsv213r4v/let-it-go.gif?dl=1)
* Merge pull request #19431 from hmarr/head-routingRafael Mendonça França2015-06-221-1/+2
|\ | | | | Respect routing precedence for HEAD requests
| * Respect routing precedence for HEAD requestsHarry Marr2015-03-201-1/+2
| | | | | | | | | | | | | | Fixes the issue described in #18764 - prevents Rack middleware from swallowing up HEAD requests that should have been matched by a higher-precedence `get` route, but still allows Rack middleware to respond to HEAD requests.
* | extract required_defaults from the conditions hash before constructing the routeAaron Patterson2015-06-082-6/+5
| | | | | | | | | | this way we can remove the strange "respond_to?" conditional in the `matches?` loop
* | Use block variable instead of globalschneems2015-06-011-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ```ruby require 'benchmark/ips' Benchmark.ips do |x| x.report("$&") { "foo".sub(/f/) { $&.upcase } } x.report("block var") { "foo".sub(/f/) {|match| match.upcase } } end ``` ``` Calculating ------------------------------------- $& 48.658k i/100ms block var 49.666k i/100ms ------------------------------------------------- $& 873.156k (± 9.3%) i/s - 4.331M block var 969.744k (± 9.2%) i/s - 4.818M ``` It's faster, and gets rid of a few "magic" global variables
* | ActionDispatch::Journey::Routes#empty? test casesValentine Valyaeff2015-05-191-1/+1
| |
* | Added ActionDispatch::Journey::Routes#empty?juggernaut-2015-05-181-0/+4
| |
* | Merge pull request #18392 from brainopia/fix_route_requirementsArthur Nogueira Neves2015-04-271-1/+1
|\ \ | | | | | | Correct route requirements by overriding defaultls
| * | Correct route requirements by overriding defaultls (fixes #18373)brainopia2015-01-081-1/+1
| | |
* | | sort_by instead of sortYang Bo2015-04-081-1/+1
| |/ |/| | | | | | | | | it is avoid sort errot within different and mixed keys. used `sort_by` + `block` to list parameter by keys. keep minimum changes
* | Merge pull request #15806 from tgxworld/partition_routes_during_setupAaron Patterson2015-03-022-8/+13
|\ \ | | | | | | Partition routes during setup.
| * | Partition routes during setup.Guo Xiang Tan2015-02-262-8/+13
| | | | | | | | | | | | | | | | | | | | | Partitioning of all the routes is currently being done during the first request. Since there is no need to clear the cache for `partitioned_routes` when adding a new route. We can move the partitioning of the routes during setup time.
* | | Revert "Merge pull request #18764 from tsun1215/master"Jeremy Kemper2015-02-261-1/+0
|/ / | | | | | | | | This reverts commit b6dd0c4ddebf5e7aab0a669915cb349ec65e5b88, reversing changes made to de9a3748c436f849dd1877851115cd94663c2725.
* / Explicitly ignored wildcard verbs from head_routesTerence Sun2015-02-081-0/+1
|/ | | | | | In match_head_routes, deleted the routes in which request.request_method was empty (matches all HTTP verbs) when responding to a HEAD request. This prevents catch-all routes (such as Racks) from intercepting the HEAD request. Fixes #18698
* Remove some comments about Ruby 1.9 behaviorsRafael Mendonça França2015-01-041-1/+1
|
* Remove deprecated option `use_route` in controller testsRafael Mendonça França2015-01-041-15/+0
|
* remove unused `#optional_parts`Sergey Alekseev2014-12-051-4/+0
| | | | | This method was copied from journey at https://github.com/rails/rails/commit/56fee39c392788314c44a575b3fd66e16a50c8b5#diff-2cfaf53c860732fea8689d6f2002594bR78. `grep -nr 'optional_parts' .`
* remove unused `#generalized_table`Sergey Alekseev2014-12-051-45/+0
| | | | This method wass copied from journey at https://github.com/rails/rails/commit/56fee39c392788314c44a575b3fd66e16a50c8b5#diff-d89de8881fc4b9f10cb3e4fc7b2463f3R53. However it looks the method was unused in journey at those point as well.
* Merge pull request #17827 from rkh/rkh-fix-or-patternAaron Patterson2014-12-011-0/+5
|\ | | | | Fix OR in Journey patterns
| * make OR in journey patterns compile to a valid regular expressionKonstantin Haase2014-11-291-0/+5
| |
* | Pass symbol as an argument instead of a blockErik Michaels-Ober2014-11-294-8/+8
|/
* CSS fix for the router visualizerBruno Sutic2014-11-251-4/+0
|
* Don't show the warning if we're already raising the error anywayGodfrey Chan2014-11-231-8/+13
| | | | | | | | | If the route set is empty, or if none of the routes matches with a score > 0, there is no point showing the deprecation message because we are already be raising the `ActionController::UrlGenerationError` mentioned in the warning. In this case it is the expected behavior and the user wouldn't have to take any actions.
* Deprecate passing an invalid name to `Formatter#generate`Godfrey Chan2014-11-231-0/+10
| | | | | | | | The internal tests that (incorrectly) relied on this were already fixed in 938d130. However, we cannot simply fix this bug because the guides prior to b7b9e92 recommended a workaround that relies on this buggy behavior. Reference #17453
* fix url generation error messageAccessd2014-10-211-1/+1
|
* Use `#tr` instead of `#gsub`Nicolas Cavigneaux2014-10-141-1/+1
| | | | | `#tr` is more efficient than `#gsub` and can be used as a drop in replacement in this context.
* Improve Journey compliance to RFC 3986Nicolas Cavigneaux2014-10-141-5/+5
| | | | | | | | | | The scanner in Journey fails to recognize routes that use literals from the sub-delims section of RFC 3986. This commit enhance the compatibility of Journey with the RFC by adding support of authorized delimiters to the scanner. Fix #17212
* Replace Array#shuffle.first with Array#sampleErik Michaels-Ober2014-10-131-2/+2
|
* Avoid duplicating routes for HEAD requests.Guo Xiang Tan2014-08-211-17/+23
| | | | | | | | Follow up to rails#15321 Instead of duplicating the routes, we will first match the HEAD request to HEAD routes. If no match is found, we will then map the HEAD request to GET routes.
* Using no_result_var in Journey's parser generatorJack Danger Canty2014-08-032-43/+33
| | | | | | | | | | | Previously the generated parser had an intermediate local variable `result` that really useful if you're building up a stateful object but Journey always discards the result argument to the reduce functions. This produces a simpler parser for anybody who actually wants to read the thing. Sadly, there's no real performance speedup with this change.
* `recall` should be `path_parameters`, also make it requiredAaron Patterson2014-07-171-3/+3
| | | | | | | | "recall" is a terrible name. This variable contains the parameters that we got from the path (e.g. for "/posts/1" it has :controller => "posts", :id => "1"). Since it contains the parameters we got from the path, "path_parameters" is a better name. We always pass path_parameters to `generate`, so lets make it required.
* Force encoding of US-ASCII to UTF-8 in unescape_uri.Karl Entwistle2014-07-101-5/+7
| | | | | | | | | Because URI paths may contain non US-ASCII characters we need to force the encoding of any unescaped URIs to UTF-8 if they are US-ASCII. This essentially replicates the functionality of the monkey patch to URI.parser.unescape in active_support/core_ext/uri.rb. Fixes #16104.
* Replace x.sort_by!.select! with x.select!.sort_by!Viktar Basharymau2014-06-201-1/+2
| | | | | | | | | The latter has the same speed as the former in the worst case and faster in general, because it is always better to sort less items. Unfortunately, `routes.select!{...}.sort_by!{...}` is not possible here because `select!` returns `nil`, so select! and sort! must be done in two steps.
* Fix request's path_info when a rack app mounted at '/'.Larry Lv2014-06-141-0/+1
| | | | Fixes issue #15511.
* no more is_a checks on instantiationAaron Patterson2014-05-291-9/+4
|
* Path::Pattern is instantiated internally, so make the contructor require a ↵Aaron Patterson2014-05-291-7/+6
| | | | strexp object
* Strexp#names is only used in a test, so rmAaron Patterson2014-05-291-4/+0
|