Skip to content

Load fileutils and etc in persist rather than at require time - #133

Merged
tpowell-progress merged 1 commit into
chef:mainfrom
tas50:perf/lazy-fileutils-etc
Sep 4, 2026
Merged

Load fileutils and etc in persist rather than at require time#133
tpowell-progress merged 1 commit into
chef:mainfrom
tas50:perf/lazy-fileutils-etc

Conversation

@tas50

@tas50 tas50 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Description

components/ruby/lib/license_acceptance/strategy/file.rb requires fileutils and etc at the top of the file, but both are reached from persist only:

  • FileUtils.mkdir_p(root_dir) — creating the license directory
  • Etc.getlogin — stamping user: into the marker file

persist runs when a license marker file is actually written. Reading acceptance state — accepted?, the common path on every subsequent run — never touches either.

Measurements

Interleaved A/B, 20 process launches per arm, Ruby 4.0.6 on arm64-darwin:

min p50 p90
require "license_acceptance/strategy/file" before 16.530 ms 21.238 ms 23.246 ms
require "license_acceptance/strategy/file" after 10.695 ms 12.903 ms 14.685 ms

8.3 ms off the median, about 39%.

Notes

  • Both requires keep their unless defined? guards, so they stay no-ops when a consumer has already loaded them.
  • persist is called once per acceptance, not in a loop, so the in-method require is not on a hot path.
  • require "date" is deliberately left alone: INVOCATION_TIME is a DateTime built at class-definition time, and making it lazy would change when it is captured and therefore what gets written into date_accepted.

Verification

  • Spec suite: 124 examples, 0 failures, including the 8 file_spec examples covering persist.
  • After a plain require "license_acceptance/strategy/file", neither FileUtils nor Etc is defined.

This is independent of #132 and the two can land in either order.

@tas50
tas50 requested review from a team as code owners August 28, 2026 05:52
@tpowell-progress
tpowell-progress force-pushed the perf/lazy-fileutils-etc branch from 91b6e51 to a4e015d Compare August 31, 2026 17:23
@tpowell-progress
tpowell-progress force-pushed the perf/lazy-fileutils-etc branch 2 times, most recently from e697d70 to 64dd296 Compare September 4, 2026 14:01
strategy/file.rb requires fileutils and etc at the top of the file, but
FileUtils.mkdir_p and Etc.getlogin are both reached from persist only, which
runs when a license marker file is actually written. Reading acceptance state,
the common path, never touches either.

Moving both requires into persist takes them off the load path. Interleaved
A/B, 20 process launches each, Ruby 4.0.6 on arm64-darwin:

  require "license_acceptance/strategy/file"  before  min 16.530  p50 21.238  p90 23.246 ms
  require "license_acceptance/strategy/file"  after   min 10.695  p50 12.903  p90 14.685 ms

8.3 ms off the median, about 39%.

Both keep their `unless defined?` guards, so they stay no-ops when a consumer
has already loaded them, and persist is called once per acceptance rather than
in a loop.

require "date" is left alone: INVOCATION_TIME is a DateTime built at class
definition time, and changing when it is captured would change what gets
written into date_accepted.

Spec suite passes, 124 examples, 0 failures, including the 8 file_spec
examples covering persist.

Signed-off-by: Tim Smith <tsmith84@proton.me>
@tpowell-progress
tpowell-progress merged commit 19b9053 into chef:main Sep 4, 2026
58 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants