SystemTools: Better GetCasePathName caching
The function GetActualCaseForPathCached
cached the whole input and output of GetCasePathName
.
By caching the calls to FindFirstFileW
instead, many redundant expensive FindFirstFileW
calls can be avoided.
For example, if we call GetActualCaseForPathCached
for the paths C:\A\B\C
, C:\A\B\D
and C:\A\B\E
(assuming that they exist),
currently FindFirstFileW
gets called for:
3 * C:\A + 3 * C:\A\B + 1 * C:\A\B\C + 1 * C:\A\B\D + 1 * C:\A\B\E
With the new caching FindFirstFileW
only gets called for:
1 * C:\A + 1 * C:\A\B + 1 * C:\A\B\C + 1 * C:\A\B\D + 1 * C:\A\B\E
This gets even better with more calls to GetActualCaseForPathCached
, which share parent directories and can be directly looked up in cache, as is the case for the majority of calls by CMake.
Benchmarking the difference of caching for CMake yields the following timings:
> hyperfine.exe -w 1 -p 'del /S /Q /F build-perf' -L state before,after 'build-{state}\bin\cmake.exe -G Ninja -B build-perf -DCMAKE_BUILD_TYPE=Debug'
Benchmark 1: build-before\bin\cmake.exe -G Ninja -B build-perf -DCMAKE_BUILD_TYPE=Debug
Time (mean ± σ): 18.195 s ± 0.126 s [User: 0.003 s, System: 0.003 s]
Range (min … max): 18.084 s … 18.529 s 10 runs
Benchmark 2: build-after\bin\cmake.exe -G Ninja -B build-perf -DCMAKE_BUILD_TYPE=Debug
Time (mean ± σ): 17.336 s ± 0.174 s [User: 0.000 s, System: 0.003 s]
Range (min … max): 17.226 s … 17.804 s 10 runs
Summary
'build-after\bin\cmake.exe -G Ninja -B build-perf -DCMAKE_BUILD_TYPE=Debug' ran
1.05 ± 0.01 times faster than 'build-before\bin\cmake.exe -G Ninja -B build-perf -DCMAKE_BUILD_TYPE=Debug'
Topic-rename: SystemTools-GetCasePathName-cache
Edited by Brad King