From bb3a348def886a7bc5c03ca5541a44919ab708b0 Mon Sep 17 00:00:00 2001 From: Matthew Woehlke Date: Wed, 30 Apr 2025 13:10:51 -0400 Subject: [PATCH] find_package: Fix performance regression in 4.0.0 release In commit e90f60f864 (find_package: Don't glob certain macOS paths, 2024-10-23, v4.0.0-rc1~579^2~1) we changed the name matching logic of `find_package` to check if a possible match is a directory before checking whether the name is a match. In some situations, this results in unnecessarily calling `stat` for a very large number of files, which can be extremely slow on some systems (especially Windows). Fix this by making the check the last thing we do before accepting a possible match. Fixes: #26817 --- Source/cmFindPackageCommand.cxx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 68a049918d..bae7d38990 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -240,12 +240,14 @@ public: for (auto i = 0ul; i < directoryLister.GetNumberOfFiles(); ++i) { char const* const fname = directoryLister.GetFile(i); // Skip entries to ignore or that aren't directories. - if (isDirentryToIgnore(fname) || !directoryLister.FileIsDirectory(i)) { + if (isDirentryToIgnore(fname)) { continue; } if (!this->Names) { - this->Matches.emplace_back(fname); + if (directoryLister.FileIsDirectory(i)) { + this->Matches.emplace_back(fname); + } } else { for (auto const& n : *this->Names) { // NOTE Customization point for @@ -258,7 +260,9 @@ public: : cmsysString_strncasecmp(fname, name.c_str(), name.length())) == 0); if (equal) { - this->Matches.emplace_back(fname); + if (directoryLister.FileIsDirectory(i)) { + this->Matches.emplace_back(fname); + } break; } }