Skip to content

Commit 4169dc4

Browse files
committed
Optimize render_each and each_part default local selection on Ruby 3+/!Windows
This uses an allocationless and regexp-free approach for symbols and strings that do not have slashes or periods. This is about 3x faster. This support requires Ruby 3 for the Symbol#name usage and does not work correctly on Windows (where \ can be a file separator), so fallback to the previous code in other cases.
1 parent fe58db3 commit 4169dc4

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
=== master
22

3+
* Optimize render_each and each_part default local selection on Ruby 3+/!Windows (jeremyevans)
4+
35
* Optimize render_each and each_part template selection when freezing app with :assume_fixed_locals render plugin option (jeremyevans)
46

57
=== 3.93.0 (2025-06-12)

lib/roda/plugins/render_each.rb

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,31 @@ def render_each(enum, template, opts=(no_opts = true; optimized_template = _cach
152152

153153
private
154154

155-
# The default local variable name to use for the template, if the :local option
156-
# is not used when calling render_each.
157-
def render_each_default_local(template)
158-
File.basename(template.to_s).sub(/\..+\z/, '').to_sym
155+
if File.basename("a/b") == "b" && File.basename("a\\b") == "a\\b" && RUBY_VERSION >= '3'
156+
# The default local variable name to use for the template, if the :local option
157+
# is not used when calling render_each.
158+
def render_each_default_local(template)
159+
# Optimize to avoid allocations when possible
160+
template = case template
161+
when Symbol
162+
s = template.name
163+
return template unless s.include?("/") || s.include?(".")
164+
s
165+
when String
166+
return template.to_sym unless template.include?("/") || template.include?(".")
167+
template
168+
else
169+
template.to_s
170+
end
171+
172+
File.basename(template).sub(/\..+\z/, '').to_sym
173+
end
174+
# :nocov:
175+
else
176+
def render_each_default_local(template)
177+
File.basename(template.to_s).sub(/\..+\z/, '').to_sym
178+
end
179+
# :nocov:
159180
end
160181

161182
if Render::COMPILED_METHOD_SUPPORT

spec/plugin/render_each_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def o.to_s; 'each' end
4848
end
4949

5050
r.is 'g' do
51-
render_each([1,2,3], "each.foo")
51+
render_each([1,2,3], :"each.foo")
5252
end
5353

5454
r.is 'h' do

0 commit comments

Comments
 (0)