]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
fix: Cache path relativization in preprocessed output
authorJoel Rosdahl <joel@rosdahl.net>
Sun, 29 Jan 2023 12:12:30 +0000 (13:12 +0100)
committerJoel Rosdahl <joel@rosdahl.net>
Sun, 29 Jan 2023 20:30:59 +0000 (21:30 +0100)
After PR #1033 and [1], a stat call is made each time a note about an
include file is found in the preprocessed output. Such calls are very
performant on Linux (and therefore unnoticed until now), but apparently
costly on Windows.

Fix this by caching the calculation of relative paths in
process_preprocessed_file.

[1]: 9a05332915d2808f4713437006b3f7c812d9fd74

Closes #1245.

src/Util.cpp
src/ccache.cpp

index 8f6b4102c1fe582199bfafe36fd08a0b2fa07e4c..e1b0d865de10cb01609939371ebc95b7933216cf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2019-2022 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2023 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -980,7 +980,8 @@ std::string
 normalize_concrete_absolute_path(const std::string& path)
 {
   const auto normalized_path = normalize_abstract_absolute_path(path);
-  return Stat::stat(normalized_path).same_inode_as(Stat::stat(path))
+  return (normalized_path == path
+          || Stat::stat(normalized_path).same_inode_as(Stat::stat(path)))
            ? normalized_path
            : path;
 }
index 5179d8d3a164f3702cda5fc07be13b0aacf13511..c26133a075258490cbafa25d233e3e649feb1970 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (C) 2002-2007 Andrew Tridgell
-// Copyright (C) 2009-2022 Joel Rosdahl and other contributors
+// Copyright (C) 2009-2023 Joel Rosdahl and other contributors
 //
 // See doc/AUTHORS.adoc for a complete list of contributors.
 //
@@ -74,6 +74,7 @@
 #include <cmath>
 #include <limits>
 #include <memory>
+#include <unordered_map>
 
 using core::Statistic;
 
@@ -457,6 +458,8 @@ process_preprocessed_file(Context& ctx, Hash& hash, const std::string& path)
     return nonstd::make_unexpected(Statistic::internal_error);
   }
 
+  std::unordered_map<std::string, std::string> relative_inc_path_cache;
+
   // Bytes between p and q are pending to be hashed.
   char* q = &(*data)[0];
   const char* p = q;
@@ -559,10 +562,18 @@ process_preprocessed_file(Context& ctx, Hash& hash, const std::string& path)
         }
         r++;
       }
+
       // p and q span the include file path.
       std::string inc_path(p, q - p);
-      inc_path = Util::normalize_concrete_absolute_path(inc_path);
-      inc_path = Util::make_relative_path(ctx, inc_path);
+      auto it = relative_inc_path_cache.find(inc_path);
+      if (it == relative_inc_path_cache.end()) {
+        auto rel_inc_path = Util::make_relative_path(
+          ctx, Util::normalize_concrete_absolute_path(inc_path));
+        relative_inc_path_cache.emplace(inc_path, rel_inc_path);
+        inc_path = std::move(rel_inc_path);
+      } else {
+        inc_path = it->second;
+      }
 
       if ((inc_path != ctx.apparent_cwd) || ctx.config.hash_dir()) {
         hash.hash(inc_path);