Skip to content

Perf optimization for url_for called w/ Hash#16504

Merged
tenderlove merged 1 commit intorails:masterfrom
schneems:schneems/fix_url_for
Aug 14, 2014
Merged

Perf optimization for url_for called w/ Hash#16504
tenderlove merged 1 commit intorails:masterfrom
schneems:schneems/fix_url_for

Conversation

@schneems
Copy link
Copy Markdown
Member

Benchmarking the existing code:

{ :only_path => options[:host].nil? }.merge!(options.symbolize_keys)) 

Against optimized code, that does not do a merge:

options = options.symbolize_keys
options[:only_path] = options[:host].nil? unless options.key?(:only_path)
options

We see a statistically significant performance gain:

Updated to not mutate incoming parameters

@schneems
Copy link
Copy Markdown
Member Author

Here's the raw benchmark/ips

Calculating -------------------------------------
     Default without     13416 i/100ms
       turbo without     15437 i/100ms
-------------------------------------------------
     Default without   247463.8 (±24.8%) i/s -    1140360 in   5.027614s
       turbo without   319883.7 (±23.3%) i/s -    1497389 in   5.059372s

Comparison:
       turbo without:   319883.7 i/s
     Default without:   247463.8 i/s - 1.29x slower

Calculating -------------------------------------
       Default with      13906 i/100ms
         turbo with      16627 i/100ms
-------------------------------------------------
       Default with    237350.7 (±24.4%) i/s -    1084668 in   5.018189s
         turbo with    302495.0 (±22.4%) i/s -    1429922 in   5.054226s

Comparison:
         turbo with :   302495.0 i/s
       Default with :   237350.7 i/s - 1.27x slower

My patch is listed a turbo.

@josevalim
Copy link
Copy Markdown
Contributor

But then we are mutating the given hash which is usually a bad practice. Thoughts?

@tenderlove
Copy link
Copy Markdown
Member

Ya, I thought we were trying to avoid mutating the parameters. ¯_(ツ)_/¯

Benchmarking the existing code:

```ruby
{ :only_path => options[:host].nil? }.merge!(options.symbolize_keys)) 
```

Against optimized code, that does not require a new hash or a merge:

```ruby
options = options.symbolize_keys
options[:only_path] = options[:host].nil? unless options.key?(:only_path)
options
```

We see a statistically significant performance gain:

![](https://www.dropbox.com/s/onocpc0zfw4kjxl/Screenshot%202014-08-14%2012.45.30.png?dl=1)

Updated to not mutate incoming parameters
@fxn
Copy link
Copy Markdown
Member

fxn commented Aug 14, 2014

Yep, while passing options as a hash literal in the method call is a common use case, of course client code may hold a reference.

@schneems
Copy link
Copy Markdown
Member Author

Updated to not mutate params. Updated screenshot here's the updated numbers:

Calculating -------------------------------------
     Default without     10903 i/100ms
       turbo without     12170 i/100ms
-------------------------------------------------
     Default without   194479.4 (±22.0%) i/s -     915852 in   5.002688s
       turbo without   218647.1 (±19.4%) i/s -    1046620 in   5.010165s

Comparison:
       turbo without:   218647.1 i/s
     Default without:   194479.4 i/s - 1.12x slower

Calculating -------------------------------------
       Default with      10473 i/100ms
         turbo with      12073 i/100ms
-------------------------------------------------
       Default with    167402.4 (±21.2%) i/s -     795948 in   5.026266s
         turbo with    209947.7 (±20.4%) i/s -    1002059 in   5.022797s

Comparison:
         turbo with :   209947.7 i/s
       Default with :   167402.4 i/s - 1.25x slower

Not as good, but still better.

tenderlove added a commit that referenced this pull request Aug 14, 2014
Perf optimization for `url_for` called w/ Hash
@tenderlove tenderlove merged commit 4751a8c into rails:master Aug 14, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants