Skip to content
1 change: 1 addition & 0 deletions libcxx/docs/ReleaseNotes/22.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Improvements and New Features
- The performance of ``unordered_set::operator=(const unordered_set&)`` has been improved by up to 5x.
- The performance of ``map::erase`` and ``set::erase`` has been improved by up to 2x
- The performance of ``find(key)`` in ``map``, ``set``, ``multimap`` and ``multiset`` has been improved by up to 2.3x
- Some reallocations are now avoided in `std::filesystem::path::lexically_relative`, resulting in a performance improvement of up to 1.7x.

Deprecations and Removals
-------------------------
Expand Down
4 changes: 3 additions & 1 deletion libcxx/src/filesystem/path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,9 @@ path path::lexically_relative(const path& base) const {
// return a path constructed with 'n' dot-dot elements, followed by the
// elements of '*this' after the mismatch.
path Result;
// FIXME: Reserve enough room in Result that it won't have to re-allocate.
constexpr size_t ElemSize = 2; // ".."
constexpr size_t SeparatorSize = 1; // separator is always a single char
Result.__reserve(ElemCount * (ElemSize + SeparatorSize) + SeparatorSize + PP.Path.size());
while (ElemCount--)
Result /= PATHSTR("..");
for (; PP; ++PP)
Expand Down
20 changes: 20 additions & 0 deletions libcxx/test/benchmarks/filesystem.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,24 @@ BENCHMARK_CAPTURE(BM_LexicallyNormal, large_path, getRandomPaths, /*PathLen*/ 32
->Range(2, 256)
->Complexity();

template <class GenInput>
void BM_LexicallyRelative(benchmark::State& st, GenInput gen, size_t PathLen) {
auto BasePath = gen(st.range(0), PathLen);
auto TargetPath = gen(st.range(0), PathLen);
benchmark::DoNotOptimize(&BasePath);
benchmark::DoNotOptimize(&TargetPath);
for (auto _ : st) {
benchmark::DoNotOptimize(TargetPath.lexically_relative(BasePath));
}
st.SetComplexityN(st.range(0));
}
BENCHMARK_CAPTURE(BM_LexicallyRelative, small_path, getRandomPaths, /*PathLen*/ 5)
->RangeMultiplier(2)
->Range(2, 256)
->Complexity();
BENCHMARK_CAPTURE(BM_LexicallyRelative, large_path, getRandomPaths, /*PathLen*/ 32)
->RangeMultiplier(2)
->Range(2, 256)
->Complexity();

BENCHMARK_MAIN();
Loading