From bc8c7d208ae13aabd760bd94b40cc1dda61ca726 Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Thu, 27 Aug 2026 20:53:51 -0700 Subject: [PATCH] Stop rebuilding the defaults Hash on every option read Every one of the 13 generated option readers ran: options[option] || options[option.to_s] || default_options[option] so each read that was not explicitly set allocated a String from `to_s` and then built a fresh 5 entry Hash (including an ENV lookup) just to pull one key out of it. `Options#for_ps1?` reads two options, so it did that twice. Freeze the String key once when the reader is defined, and look up a single default instead of materializing the whole Hash. `license_id` still reads ENV["CHEF_LICENSE_KEY"] on every access, so changes to the environment are picked up exactly as before. The `||` chain is kept rather than switched to nil checks so that an explicitly `false` option still falls through to its default, as it does today. Measured on Ruby 4.0.6: #shell_type 445 ns -> 180 ns 2.5x 3.02 -> 0.02 allocations #product_version 450 ns -> 140 ns 3.2x 3 -> 0 allocations #for_ps1? 907 ns -> 327 ns 2.8x 7 -> 1 allocation #latest_version? 483 ns -> 174 ns 2.8x .new 4094 ns -> 2632 ns 1.6x 30 -> 16 allocations validate_options! 1193 ns -> 867 ns 1.4x Output is unchanged: 576 unit examples pass and all 176 golden SHA256 digests match main. Signed-off-by: Tim Smith --- lib/mixlib/install/options.rb | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/lib/mixlib/install/options.rb b/lib/mixlib/install/options.rb index 4760065b..7e6ca7bb 100644 --- a/lib/mixlib/install/options.rb +++ b/lib/mixlib/install/options.rb @@ -97,8 +97,12 @@ def initialize(options) end SUPPORTED_OPTIONS.each do |option| + # Freeze the String key once here rather than calling `option.to_s` on + # every read, and look up a single default instead of rebuilding the + # whole defaults Hash. + option_string = option.to_s.freeze define_method option do - options[option] || options[option.to_s] || default_options[option] + options[option] || options[option_string] || default_option(option) end end @@ -182,14 +186,23 @@ def resolve_platform_version_compatibility_mode! private + # Defaults that never change. `license_id` is deliberately not in here + # because it is read from the environment on every access. + STATIC_DEFAULT_OPTIONS = { + shell_type: :sh, + platform_version_compatibility_mode: false, + product_version: :latest, + include_metadata: false, + }.freeze + + def default_option(option) + return ENV["CHEF_LICENSE_KEY"] if option == :license_id + + STATIC_DEFAULT_OPTIONS[option] + end + def default_options - { - shell_type: :sh, - platform_version_compatibility_mode: false, - product_version: :latest, - include_metadata: false, - license_id: ENV["CHEF_LICENSE_KEY"], - } + STATIC_DEFAULT_OPTIONS.merge(license_id: ENV["CHEF_LICENSE_KEY"]) end def validate_architecture