Skip to content

Instantly share code, notes, and snippets.

@tenderlove
Created February 27, 2020 23:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tenderlove/8be9006e1d410398afdad30f4657e666 to your computer and use it in GitHub Desktop.
Save tenderlove/8be9006e1d410398afdad30f4657e666 to your computer and use it in GitHub Desktop.
# frozen_string_literal: true
require "active_record"
require "active_record/railties/collection_cache_association_loading"
require "action_controller"
require "action_view"
require "tmpdir"
require "benchmark/ips"
ActionView::PartialRenderer.prepend(ActiveRecord::Railties::CollectionCacheAssociationLoading)
class TestController < ActionController::Base
def _prefixes; ["."]; end # Search the current directory rather than "test/"
end
class Neat
def to_partial_path; "thing"; end
end
class NoYield
def to_partial_path; "no_yield"; end
end
def recurse(cv, depth)
if depth == 0
cv.render("thing") { "World" }
else
cv.render("thing") { recurse(cv, depth - 1) }
end
end
def recurse_with_object(cv, obj, depth)
if depth == 0
cv.render(obj) { "World" }
else
cv.render(obj) { recurse_with_object(cv, obj, depth - 1) }
end
end
def allocs
x = GC.stat(:total_allocated_objects)
yield
GC.stat(:total_allocated_objects) - x
end
Dir.mktmpdir do |dir|
TestController.view_paths = dir
File.write File.join(dir, "_thing.html.erb"), "Hello <%= yield %>"
File.write File.join(dir, "_no_yield.html.erb"), "Hello World"
cv = TestController.new.view_context
obj = Neat.new
collection = [NoYield.new] * 50
yield_collection = [Neat.new] * 50
# heat
cv.render("thing") { "World" }
cv.render(obj) { "World" }
cv.render(collection)
puts "Allocations for partial rendering with object"
10.times do |i|
p i => allocs { recurse_with_object(cv, obj, i) }
end
puts "Allocations for partial rendering"
10.times do |i|
p i => allocs { recurse(cv, i) }
end
puts "Allocations for collection rendering"
p 0 => allocs { cv.render(collection) }
Benchmark.ips do |x|
x.report("shallow render") { cv.render("thing") { "World" } }
x.report("deep render") { recurse(cv, 30) }
x.report("shallow render obj") { cv.render(obj) { "World" } }
x.report("deep render obj") { recurse_with_object(cv, obj, 30) }
x.report("collection render") { cv.render(collection) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment