Browse Source

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
Matthew Woehlke 7 months ago
parent
commit
bb3a348def
1 changed files with 7 additions and 3 deletions
  1. 7 3
      Source/cmFindPackageCommand.cxx

+ 7 - 3
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;
             }
           }