Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Eliminate a hash allocation when rendering templates
The `**options` in this code allocates a hash. Most template renders are probably not cached, so if we return a little early, we can save a hash allocation on each render call. Here is an allocation benchmark: ```ruby require "active_record" require "active_record/railties/collection_cache_association_loading" require "action_controller" require "action_view" require "tmpdir" ActionView::PartialRenderer.prepend(ActiveRecord::Railties::CollectionCacheAssociationLoading) class TestController < ActionController::Base def _prefixes; []; end # Search the current directory rather than "test/" end Dir.mktmpdir do |dir| TestController.view_paths = dir File.write File.join(dir, "_thing.html.erb"), "Hello <%= yield %>" cv = TestController.new.view_context # heat cv.render("thing") { "World" } # delete the line below and allocations go *way* down def recurse(cv, depth) if depth == 0 cv.render("thing") { "World" } else cv.render("thing") { recurse(cv, depth - 1) } end end def allocs x = GC.stat(:total_allocated_objects) yield GC.stat(:total_allocated_objects) - x end 10.times do |i| p i => allocs { recurse(cv, i) } end end ``` Before: ``` $ be ruby thing.rb {0=>58} {1=>77} {2=>115} {3=>153} {4=>192} {5=>231} {6=>270} {7=>309} {8=>348} {9=>387} ``` After: ``` $ be ruby thing.rb {0=>55} {1=>73} {2=>109} {3=>145} {4=>182} {5=>219} {6=>256} {7=>293} {8=>330} {9=>367} ``` I realize this is a "micro bench", but we're seeing the same line pop up in benchmarks from our app. I extracted this micro-bench from one we're using to test renders inside our app.
- Loading branch information