Semantic Diff

#9285 Key a build file by its own path when it is already normal

1 commit

70da3d1bc43caa96214c942f72db9296f83a9db6..pr-9285

dc61691db · JonoPrest · Nov 09, 2026, 14:38 UTC

Key a build file by its own path when it is already normal

Why

Build_file_store.key split every path into segments and joined them again, also when no segment was ., .. or empty and the result was the path itself. The store keys every read, so a request that looks up an interface along the load path built a list and a new string for each directory it tried, about 200 words a lookup.

key now first checks, without allocating, that the path has no ., .. or empty segment (other than the leading one of an absolute path) and no separator other than /, and then returns the path itself. Other paths are normalized as before, so every spelling of a file keeps the same entry.

key is now in the interface, so that a test can compare it with a copy of the previous normalization: on edge cases (//, trailing /, . and .. anywhere, ... and .a names, the empty path, backslashes, drive letters, UNC paths), on every path of up to 8 characters made of /, ., \ and a, and on 20,000 seeded random paths. The copy reads Sys.win32 like key, so the test holds on Windows too.

Measured with scripts/compilerBenchmarks.js against the previous commit: allocated words -2.27% in the builds of tests/tests (build/clean -2.48%), -0.78% in the generated projects, the files compiled one by one unchanged (the store is only used in a build). On a 552 module React app (clean build) the build allocates 2.47% fewer words at one domain. Its user time is 1.2% lower at one domain (40 alternating pairs, 95% CI 0.5% to 2.1%) and 2.0% lower at the default domains (15 pairs, 1.0% to 2.8%); its wall time is unchanged within the noise.

Review

  • Can a key change? No: a path that passes the check splits into segments that the normalization keeps in order, so joining them gives the path back; any other path takes the previous code.
  • What about Windows? There \ is also a separator, and a path with one takes the previous code; a path with only / separators, such as C:/a/b, is split the same way on both platforms.