From a05445fb400108e60ede7d377cf3b26a0392eb24 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 23 Dec 2020 08:38:52 +0000 Subject: config: config_fh_parse: micro-optimize We can avoid a slow regexp capture and instead and rely on rindex + substr to extract the section from the config file. Then we use the defined-or-assignment (//=) operator combined with the documented return value of `push' to ensure @section_order is unique without repeating a hash lookup. Finally, we avoid short-lived variables inside the loop and declare them subroutine-wide to knock a teeny bit of allocation time. Combined, these optimizations bring the ~1.22s PublicInbox::Config->new time down to ~0.98s with 50K inboxes. --- lib/PublicInbox/Config.pm | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'lib/PublicInbox/Config.pm') diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm index 4d143c6e..60107d45 100644 --- a/lib/PublicInbox/Config.pm +++ b/lib/PublicInbox/Config.pm @@ -132,20 +132,15 @@ sub default_file { sub config_fh_parse ($$$) { my ($fh, $rs, $fs) = @_; - my %rv; - my (%section_seen, @section_order); + my (%rv, %section_seen, @section_order, $line, $k, $v, $section, $cur); local $/ = $rs; - while (defined(my $line = <$fh>)) { + while (defined($line = <$fh>)) { # performance critical with giant configs chomp $line; - my ($k, $v) = split($fs, $line, 2); - my ($section) = ($k =~ /\A(\S+)\.[^\.]+\z/); - unless (defined $section_seen{$section}) { - $section_seen{$section} = 1; - push @section_order, $section; - } + ($k, $v) = split($fs, $line, 2); + $section = substr($k, 0, rindex($k, '.')); + $section_seen{$section} //= push(@section_order, $section); - my $cur = $rv{$k}; - if (defined $cur) { + if (defined($cur = $rv{$k})) { if (ref($cur) eq "ARRAY") { push @$cur, $v; } else { -- cgit v1.2.3-24-ge0c7