From f5ee3331e336db8d8da543d2cb67b169dab57d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C5=8Dan?= Date: Sat, 28 Mar 2026 01:31:00 -0600 Subject: [PATCH] optimization: cache contents() in __open and _io_file_mock_open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cache the result of $mock_file->contents() before its first use in both __open and _io_file_mock_open. For directories, contents() scans all keys of %files_being_mocked and sorts — calling it twice per open() was redundant work that grows linearly with mock count. Co-Authored-By: Claude Opus 4.6 --- lib/Test/MockFile.pm | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/Test/MockFile.pm b/lib/Test/MockFile.pm index deac888..9cdd2aa 100644 --- a/lib/Test/MockFile.pm +++ b/lib/Test/MockFile.pm @@ -2800,8 +2800,11 @@ sub _io_file_mock_open { return; } + # Cache contents() — it's non-trivial for directories (scans %files_being_mocked). + my $contents = $mock_file->contents(); + # If contents is undef and reading, file doesn't exist - if ( !defined $mock_file->contents() && grep { $mode eq $_ } qw/< +contents() ) { + if ( defined $contents ) { # Existing file: check file permissions my $need = 0; $need |= 4 if $rw =~ /r/; @@ -3136,8 +3139,11 @@ sub __open (*;$@) { return undef; } + # Cache contents() — it's non-trivial for directories (scans %files_being_mocked). + my $contents = $mock_file->contents(); + # If contents is undef, we act like the file isn't there. - if ( !defined $mock_file->contents() && grep { $mode eq $_ } qw/< +contents() ) { + if ( defined $contents ) { my $need = 0; $need |= 4 if $rw =~ /r/; $need |= 2 if $rw =~ /w/;