Bug#917478: popularity-contest: Improve performance (4x faster)
Package: popularity-contest
Version: 1.67
Severity: minor
Tags: patch
Dear Maintainer,
For each installed packages, popcon globs the complete list of files
in /var/lib/dpkg/info.
This is very slow as I noticed that popcon takes more than a minute of CPU
time on my modest laptop, which is enough to start the fan.
I'm attaching a patch that lists only once /var/lib/dpkg/info and associates
each .list file with a package.
I don't see any difference in /usr/sbin/popularity-contest output.
And the CPU time goes from 1min08s to 0min14s.
-- System Information:
Debian Release: buster/sid
APT prefers unstable-debug
APT policy: (500, 'unstable-debug'), (500, 'unstable'), (500, 'testing'), (1, 'experimental-debug'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 4.17.0-3-amd64 (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8), LANGUAGE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages popularity-contest depends on:
ii debconf [debconf-2.0] 1.5.69
ii dpkg 1.19.2
Versions of packages popularity-contest recommends:
ii cron [cron-daemon] 3.0pl1-130
ii exim4-daemon-light [mail-transport-agent] 4.91-8+b1
ii gnupg 2.2.10-3
Versions of packages popularity-contest suggests:
ii anacron 2.3-27
pn tor <none>
pn torsocks <none>
-- debconf-show failed
--- /usr/sbin/popularity-contest 2018-08-09 20:41:19.000000000 +0200
+++ popularity-contest 2018-12-27 22:51:27.710362640 +0100
@@ -119,6 +119,19 @@
close DIVERSIONS;
}
+my %pkgs_files = ();
+
+if (opendir(my $DPKG_DB, $dpkg_db))
+{
+ for my $e (readdir($DPKG_DB)) {
+ if ($e =~ m/^([^:]+) .*? \. list$/x) {
+ $pkgs_files{$1} ||= [];
+ push @{$pkgs_files{$1}}, "$dpkg_db/$e";
+ }
+ }
+ closedir($DPKG_DB);
+}
+
# Read dpkg database of installed packages
open PACKAGES, "dpkg-query --show --showformat='\${status} \${package}\\n'|";
while (<PACKAGES>)
@@ -128,7 +141,7 @@
my $bestatime = undef;
my $list;
$popcon{$pkg}=[0,0,$pkg,"<NOFILES>"];
- foreach ("$dpkg_db/$pkg.list", glob("$dpkg_db/$pkg:*.list"))
+ foreach (@{$pkgs_files{$pkg}})
{
open FILES, $_ or next;
while (<FILES>)
Reply to: