From 8e8507a128edd2e050df144b455b8e8948179be7 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Wed, 18 Jun 2025 14:12:24 -0400 Subject: [PATCH 1/4] Optimize array! DSL for blocks --- lib/jbuilder/jbuilder_template.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/jbuilder/jbuilder_template.rb b/lib/jbuilder/jbuilder_template.rb index 357979d..1d4aaf5 100644 --- a/lib/jbuilder/jbuilder_template.rb +++ b/lib/jbuilder/jbuilder_template.rb @@ -118,14 +118,16 @@ def target! @cached_root || super end - def array!(collection = EMPTY_ARRAY, *args, &block) + def array!(collection = EMPTY_ARRAY, *args) options = args.first if _partial_options?(options) options[:collection] = collection _render_partial_with_options options + elsif ::Kernel.block_given? + _array(collection, args) { |x| yield x } else - _array collection, args, &block + _array collection, args end end From b1edf915b23ad5a93dbdedebaf51f4fe8a6c4407 Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Wed, 18 Jun 2025 15:19:57 -0400 Subject: [PATCH 2/4] Update array! benchmark --- benchmarks/jbuilder_template/array_dsl.rb | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/benchmarks/jbuilder_template/array_dsl.rb b/benchmarks/jbuilder_template/array_dsl.rb index cb31e17..7e9a1cd 100644 --- a/benchmarks/jbuilder_template/array_dsl.rb +++ b/benchmarks/jbuilder_template/array_dsl.rb @@ -7,14 +7,13 @@ Post = Struct.new(:id, :body) json = JbuilderTemplate.new nil -posts = 3.times.map { Post.new(it, "Post ##{it}") } Benchmark.ips do |x| - x.report('before') do - json.array!(nil) + x.report('before') do |n| + n.times { json.array! } end - x.report('after') do - json.array!(nil) + x.report('after') do |n| + n.times { json.array! } end x.hold! 'temp_array_ips' @@ -24,8 +23,8 @@ json = JbuilderTemplate.new nil Benchmark.memory do |x| - x.report('before') { json.array! posts, :id, :body } - x.report('after') { json.array! posts, :id, :body } + x.report('before') { json.array! } + x.report('after') { json.array! } x.hold! 'temp_array_memory' x.compare! From 37611a82081264f951b17bc1cc85a8efd1e0b94d Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Wed, 18 Jun 2025 15:20:18 -0400 Subject: [PATCH 3/4] Add benchmark for array! with block --- .../jbuilder_template/array_dsl_block.rb | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 benchmarks/jbuilder_template/array_dsl_block.rb diff --git a/benchmarks/jbuilder_template/array_dsl_block.rb b/benchmarks/jbuilder_template/array_dsl_block.rb new file mode 100644 index 0000000..f29f4bb --- /dev/null +++ b/benchmarks/jbuilder_template/array_dsl_block.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'benchmark/ips' +require 'benchmark/memory' +require_relative '../../lib/jbuilder' +require_relative '../../lib/jbuilder/jbuilder_template' + +Post = Struct.new(:id, :body) +json = JbuilderTemplate.new nil +array = [1, 2, 3] + +Benchmark.ips do |x| + x.report('before') do |n| + n.times do + json.array! array do |item| + end + end + end + x.report('after') do |n| + n.times do + json.array! array do |item| + end + end + end + + x.hold! 'temp_array_ips' + x.compare! +end + +json = JbuilderTemplate.new nil + +Benchmark.memory do |x| + x.report('before') do + json.array! array do |item| + end + end + x.report('after') do + json.array! array do |item| + end + end + + x.hold! 'temp_array_memory' + x.compare! +end From b69a3e2fbd399c69be419585428c06bdaab42f1c Mon Sep 17 00:00:00 2001 From: Michael Oberegger Date: Wed, 18 Jun 2025 15:24:28 -0400 Subject: [PATCH 4/4] Add benchmark for array! partial --- benchmarks/partials/array_dsl.rb | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 benchmarks/partials/array_dsl.rb diff --git a/benchmarks/partials/array_dsl.rb b/benchmarks/partials/array_dsl.rb new file mode 100644 index 0000000..2ee724d --- /dev/null +++ b/benchmarks/partials/array_dsl.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'benchmark/ips' +require 'benchmark/memory' +require_relative 'setup' + +POST_PARTIAL = <<-JBUILDER + json.extract! post, :id, :body +JBUILDER + +PARTIALS = { "_post.json.jbuilder" => POST_PARTIAL } + +Post = Struct.new(:id, :body) + +view = build_view(fixtures: PARTIALS) +json = JbuilderTemplate.new view +posts = 3.times.map { Post.new(it, "Post ##{it}") } + +Benchmark.ips do |x| + x.report('before') do |n| + n.times { json.array! posts, partial: "post", as: :post } + end + + x.report('after') do |n| + n.times { json.array! posts, partial: "post", as: :post } + end + + x.hold! 'temp_array_results_ips' + x.compare! +end + +json = JbuilderTemplate.new view + +Benchmark.memory do |x| + x.report('before') do + json.array! posts, partial: "post", as: :post + end + + x.report('after') do + json.array! posts, partial: "post", as: :post + end + + x.hold! 'temp_array_results_memory' + x.compare! +end