[debhelper-devel] [debhelper] 03/03: dh_install: Optimize some calls with xargs
Niels Thykier
nthykier at moszumanska.debian.org
Mon Jun 26 14:44:31 UTC 2017
This is an automated email from the git hooks/post-receive script.
nthykier pushed a commit to branch master
in repository debhelper.
commit e15f79892cb999d95db88d160d5c5d0778037bf2
Author: Niels Thykier <niels at thykier.net>
Date: Mon Jun 26 14:30:37 2017 +0000
dh_install: Optimize some calls with xargs
The following are common pattern seen in install files:
"""
some/path/*
some/path/*.foo*
"""
These patterns all cause dh_install to issue one "cp" per file matched
in "some/path" (the first one matching all files in the directory).
For patterns with many matches, this triggers a considerable overhead
by the number of fork+exec calls.
This patch makes dh_install bulk "cp" calls provided that:
* The matched files all end in the same destination directory.
(which might not be the case for e.g. "foo/*/bar" )
* There are no "--exclude" in play (as that triggers a vastly more
complicated case).
Signed-off-by: Niels Thykier <niels at thykier.net>
---
debian/changelog | 3 +++
dh_install | 45 ++++++++++++++++++++++++++++++++++++++-------
2 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 9c192de..329e4f9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -28,6 +28,9 @@ debhelper (10.5.1) UNRELEASED; urgency=medium
* dh_installman: When re-encoding manpages, use the actual manpages as
tasks to split rather than packages. This provides a much better
performance if the manpages are unevenly split between the packages.
+ * dh_install: Optimize some patterns into bulked "cp" calls. This
+ optimization is only applicable in some cases (notably, it is always
+ disabled by --exclude).
-- Niels Thykier <niels at thykier.net> Sun, 25 Jun 2017 18:02:30 +0000
diff --git a/dh_install b/dh_install
index 9b0eb0a..62ed9c8 100755
--- a/dh_install
+++ b/dh_install
@@ -178,13 +178,12 @@ foreach my $package (getpackages()) {
@install = map { [$_] } map { @$_ } @install if $dh{AUTODEST};
foreach my $set (@install) {
- my $dest;
-
+ my ($dest, @filelist);
+
if (@$set > 1) {
$dest=pop @$set;
}
- my @filelist;
foreach my $glob (@$set) {
my @found = glob "$srcdir/$glob";
my $matched = 0;
@@ -226,15 +225,37 @@ foreach my $package (getpackages()) {
# ... because then we can short-curcit here.
next if $skip_install or $missing_files;
+ if (not $exclude) {
+ # Without $exclude and if everything is installed in the same directory, it is trivial
+ # to bulk them cp calls via xargs.
+ if (not $dest and @filelist > 1) {
+ my $same = 1;
+ my $common_dest;
+ for my $src (@filelist) {
+ my $target_dest = compute_dest($src);
+ if (not defined($common_dest)) {
+ $common_dest = $target_dest;
+ } elsif ($common_dest ne $target_dest) {
+ $same = 0;
+ last;
+ }
+ }
+ $dest = $common_dest if ($same and $common_dest);
+ }
+ if ($dest and @filelist > 1) {
+ # Make sure the destination directory exists.
+ install_dir("$tmp/$dest");
+ xargs(\@filelist, "cp", '--reflink=auto', "-a", XARGS_INSERT_PARAMS_HERE, "$tmp/$dest/");
+ next;
+ }
+ }
+
foreach my $src (@filelist) {
my $target_dest = $dest;
if (! defined $target_dest) {
# Guess at destination directory.
- $target_dest = $src;
- $target_dest =~ s/^(.*\/)?\Q$srcdir\E\///;
- $target_dest =~ s/^(.*\/)?debian\/tmp\///;
- $target_dest = dirname("/".$target_dest);
+ $target_dest = compute_dest($src);
}
# Make sure the destination directory exists.
@@ -279,6 +300,16 @@ if ($dh{LIST_MISSING} || $dh{FAIL_MISSING}) {
doit("dh_missing", @options);
}
+sub compute_dest {
+ my ($dest) = @_;
+
+ $dest =~ s/^(.*\/)?\Q$srcdir\E\///;
+ $dest =~ s/^(.*\/)?debian\/tmp\///;
+ $dest = dirname("/".$dest);
+
+ return $dest;
+}
+
=head1 LIMITATIONS
B<dh_install> cannot rename files or directories, it can only install them
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debhelper/debhelper.git
More information about the debhelper-devel
mailing list