From 3bf6df0e5caafa9ad3bf8792bd0f1c1d1f475757 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Sat, 19 Apr 2025 23:47:36 -0700 Subject: [PATCH 1/2] Avoid an array allocation per element in list passed to seplist The array allocation was because the keyword splat expression is not recognized as safe by the compiler. Also avoid unnecessary >= method call per element. This uses a private constant to avoid unnecessary work at runtime. I assume the only reason this code is needed is because v may end with a ruby2_keywords hash that we do not want to treat as keywords. This issue was found by the performance warning in Ruby feature 21274. --- lib/pp.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/pp.rb b/lib/pp.rb index 3320621..d86bfb9 100644 --- a/lib/pp.rb +++ b/lib/pp.rb @@ -276,15 +276,20 @@ def comma_breakable def seplist(list, sep=nil, iter_method=:each) # :yield: element sep ||= lambda { comma_breakable } first = true + kwsplat = EMPTY_HASH list.__send__(iter_method) {|*v| if first first = false else sep.call end - RUBY_VERSION >= "3.0" ? yield(*v, **{}) : yield(*v) + kwsplat ? yield(*v, **kwsplat) : yield(*v) } end + EMPTY_HASH = if RUBY_VERSION >= "3.0" + {}.freeze + end + private_constant :EMPTY_HASH # A present standard failsafe for pretty printing any given Object def pp_object(obj) From efe5bc878fa5308f6a8e5953a60649b086387e7f Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Tue, 22 Apr 2025 07:14:33 -0700 Subject: [PATCH 2/2] Rename EMPTY_HASH to EMPTY_KWHASH --- lib/pp.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pp.rb b/lib/pp.rb index d86bfb9..1c24ca0 100644 --- a/lib/pp.rb +++ b/lib/pp.rb @@ -276,7 +276,7 @@ def comma_breakable def seplist(list, sep=nil, iter_method=:each) # :yield: element sep ||= lambda { comma_breakable } first = true - kwsplat = EMPTY_HASH + kwsplat = EMPTY_KWHASH list.__send__(iter_method) {|*v| if first first = false @@ -286,10 +286,10 @@ def seplist(list, sep=nil, iter_method=:each) # :yield: element kwsplat ? yield(*v, **kwsplat) : yield(*v) } end - EMPTY_HASH = if RUBY_VERSION >= "3.0" + EMPTY_KWHASH = if RUBY_VERSION >= "3.0" {}.freeze end - private_constant :EMPTY_HASH + private_constant :EMPTY_KWHASH # A present standard failsafe for pretty printing any given Object def pp_object(obj)