Rewrite std::filesystem::path iterators and parser
authorEric Fiselier <eric@efcs.ca>
Sun, 30 Oct 2016 23:30:38 +0000 (23:30 +0000)
committerEric Fiselier <eric@efcs.ca>
Sun, 30 Oct 2016 23:30:38 +0000 (23:30 +0000)
commit1467a197e548b9f8fa04328b69731b022c190de1
treee26e5e47dc9f62a5f3b4d33c59fce590b750aeb0
parentb2461ce33acdd68eb611ef4c204b000aa3b49338
Rewrite std::filesystem::path iterators and parser

This patch entirely rewrites the parsing logic for paths. Unlike the previous
implementation this one stores information about the current state; For example
if we are in a trailing separator or a root separator. This avoids the need for
extra lookahead (and extra work) when incrementing or decrementing an iterator.
Roughly this gives us a 15% speedup over the previous implementation.

Unfortunately this implementation is still a lot slower than libstdc++'s.
Because libstdc++ pre-parses and splits the path upon construction their
iterators are trivial to increment/decrement. This makes libc++ lazy parsing
100x slower than libstdc++. However the pre-parsing libstdc++ causes a ton
of extra and unneeded allocations when constructing the string. For example
`path("/foo/bar/")` would require at least 5 allocations with libstdc++
whereas libc++ uses only one. The non-allocating behavior is much preferable
when you consider filesystem usages like 'exists("/foo/bar/")'.

Even then libc++'s path seems to be twice as slow to simply construct compared
to libstdc++. More investigation is needed about this.

llvm-svn: 285526
libcxx/benchmarks/CMakeLists.txt
libcxx/include/experimental/filesystem
libcxx/src/experimental/filesystem/path.cpp
libcxx/test/libcxx/experimental/filesystem/class.path/path.itr/iterator_db.pass.cpp [new file with mode: 0644]