From 1b2bb72f7b5da8419be5521b0c1a25eab6ce6f06 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 27 Sep 2017 02:10:07 +0200 Subject: Dpkg::Control::HashCore: Optimize trailing space matching on parse() We remove the trailing space after the chomp, so that we cover the common case of a single \n with chomp, and do not need to check for trailing spaces more than once while parsing. We preserve the chomp'ed string to be used for the Armor Header checks, which have a different set of allowed whitespace, than what \s covers. --- scripts/Dpkg/Control/HashCore.pm | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'scripts/Dpkg/Control') diff --git a/scripts/Dpkg/Control/HashCore.pm b/scripts/Dpkg/Control/HashCore.pm index a3ea4bc96..3504e99c2 100644 --- a/scripts/Dpkg/Control/HashCore.pm +++ b/scripts/Dpkg/Control/HashCore.pm @@ -199,8 +199,14 @@ sub parse { local $_; while (<$fh>) { + # In the common case there will be just a trailing \n character, + # so using chomp here which is very fast will avoid the latter + # s/// doing anything, which gives usa significant speed up. chomp; - next if m/^\s*$/ and $paraborder; + my $armor = $_; + s/\s*$//; + + next if length == 0 and $paraborder; next if substr($_, 0, 1) eq '#'; $paraborder = 0; if (m/^(\S+?)\s*:\s*(.*)$/) { @@ -214,7 +220,6 @@ sub parse { $self->parse_error($desc, g_('duplicate field %s found'), $name); } } - $value =~ s/\s*$//; $self->{$name} = $value; $cf = $name; } elsif (m/^\s(\s*\S.*)$/) { @@ -222,13 +227,12 @@ sub parse { unless (defined($cf)) { $self->parse_error($desc, g_('continued value line not in field')); } - $line =~ s/\s*$//; if ($line =~ /^\.+$/) { $line = substr $line, 1; } $self->{$cf} .= "\n$line"; - } elsif (m/^\s*$/ || - ($expect_pgp_sig && m/^-----BEGIN PGP SIGNATURE-----[\r\t ]*$/)) { + } elsif (length == 0 || + ($expect_pgp_sig && $armor =~ m/^-----BEGIN PGP SIGNATURE-----[\r\t ]*$/)) { if ($expect_pgp_sig) { # Skip empty lines $_ = <$fh> while defined && m/^\s*$/; @@ -254,7 +258,7 @@ sub parse { $$self->{is_pgp_signed} = 1; } last; # Finished parsing one block - } elsif (m/^-----BEGIN PGP SIGNED MESSAGE-----[\r\t ]*$/) { + } elsif ($armor =~ m/^-----BEGIN PGP SIGNED MESSAGE-----[\r\t ]*$/) { $expect_pgp_sig = 1; if ($$self->{allow_pgp} and not $parabody) { # Skip OpenPGP headers -- cgit v1.2.3