diff --git a/dh_setup_copyright b/dh_setup_copyright
index dac108f31bc6e0bc2fea95a036012536771935b4..91dbe890d72a6a0a5cccc96daa6bad7008afc982 100755
--- a/dh_setup_copyright
+++ b/dh_setup_copyright
@@ -317,6 +317,20 @@ sub scan_binary_shlibs {
 	}
 }
 
+sub collect_sources_by_basename {
+	my @sources = find_local('.', { 'exclude' => ['debian'] });
+	my %sources_by_basename = ();
+	foreach my $source (@sources) {
+		# Clean up stuff like `./`.
+		$source = File::Spec->canonpath($source);
+
+		my $with_basename = $sources_by_basename{basename $source} ||= [];
+		push @$with_basename, $source;
+	}
+
+	\%sources_by_basename
+}
+
 # Returns the number of path components shared between the tails of the two
 # arguments.
 #
@@ -335,30 +349,21 @@ sub common_path_suffix_length {
 }
 
 sub build_copied_sources_map {
-	my ($tmpdir, $others, $metadata) = @_;
+	my ($tmpdir, $others, $sources_by_basename, $metadata) = @_;
 
 	my $copied_sources = $metadata->{'copied_sources'};
 
-	my @sources = find_local('.', { 'exclude' => ['debian'] });
 	foreach my $file (@$others) {
-		my $base = basename $file;
+		my $unscored_matches = $sources_by_basename->{basename $file};
+		next if !defined $unscored_matches;
 
 		# Assign a "score" to each matching file based on the number of path
 		# components in common, so that we'll be more likely to match e.g.
 		# "/usr/include/test" as "src/include/test" than "examples/test".
-		my @matches = ();
-		foreach my $source (@sources) {
-			# Clean up stuff like `./`.
-			$source = File::Spec->canonpath($source);
-			if ($base =~ /(^|\/)\Q@{[basename $source]}\E$/) {
-				my $score = common_path_suffix_length $file, $source;
-				push @matches, [$score, $source];
-			}
-		}
-
-		if (!@matches) {
-			next;
-		}
+		my @matches = map {
+			my $score = common_path_suffix_length $file, $_;
+			[$score, $_]
+		} @$unscored_matches;
 
 		my $file_sha256 = Digest::SHA->new('256')->addfile("$tmpdir/$file", 'b')->hexdigest;
 		# Skip if...
@@ -442,7 +447,9 @@ for my $package (@{$dh{DOPACKAGES}}) {
 	extract_filenames($fname_list, $tmp, @binaries);
 	process_external_sources("$tmp/$fname_list", "$tmp/$fname_external_dir", \%metadata);
 	scan_binary_shlibs($tmp, \@binaries, \%metadata);
-	build_copied_sources_map($tmp, \@others, \%metadata);
+
+	my $sources_by_basename = collect_sources_by_basename;
+	build_copied_sources_map($tmp, \@others, $sources_by_basename, \%metadata);
 
 	if (%metadata) {
 		open my $meta_handle, '>', "$tmp/$fname_metadata" or die "Failed to open $fname_metadata: $!";