This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR libstdc++/71044 optimize std::filesystem::path construction

This new implementation has a smaller footprint than the previous
implementation, due to replacing std::vector<_Cmpt> with a custom pimpl
type that only needs a single pointer. The _M_type enumeration is also
combined with the pimpl type, by using a tagged pointer, reducing
sizeof(path) further still.

Construction and modification of paths is now done more efficiently, by
splitting the input into a stack-based buffer of string_view objects
instead of a dynamically-allocated vector containing strings. Once the
final size is known only a single allocation is needed to reserve space
for it. The append and concat operations no longer require constructing
temporary path objects, nor re-parsing the entire native pathname.

This results in algorithmic improvements to path construction, and
working with large paths is much faster.

	PR libstdc++/71044
	* include/bits/fs_path.h (path::path(path&&)): Add noexcept when
	appropriate. Move _M_cmpts instead of reparsing the native pathname.
	(path::operator=(const path&)): Do not define as defaulted.
	(path::operator/=, path::append): Call _M_append.
	(path::concat): Call _M_concat.
	(path::path(string_type, _Type): Change type of first parameter to
	(path::_M_append(string_type), path::_M_concat(string_type)): New
	member functions.
	(path::_S_is_dir_sep): Replace with non-member is_dir_sep.
	(path::_M_trim, path::_M_add_root_name, path::_M_add_root_dir)
	(path::_M_add_filename): Remove.
	(path::_M_type()): New member function to replace _M_type data member.
	(path::_List): Define new struct type instead of using std::vector.
	(path::_Cmpt::_Cmpt(string_type, _Type, size_t)): Change type of
	first parameter to basic_string_view<value_type>.
	(path::operator+=(const path&)): Do not define inline.
	(path::operator+=(const string_type&)): Call _M_concat.
	(path::operator+=(const value_type*)): Likewise.
	(path::operator+=(value_type)): Likewise.
	(path::operator+=(basic_string_view<value_type>)): Likewise.
	(path::operator/=(const path&)): Do not define inline.
	(path::_M_append(path)): Remove.
	* python/libstdcxx/v6/ (StdPathPrinter): New printer that
	understands the new path::_List type.
	* src/filesystem/ (is_dir_sep): New function to replace
	(path::_Parser): New helper class to parse strings as paths.
	(path::_List::_Impl): Define container type for path components.
	(path::_List): Define members.
	(path::operator=(const path&)): Define explicitly, to provide the
	strong exception safety guarantee.
	(path::operator/=(const path&)): Implement manually by processing
	each component of the argument, rather than using _M_split_cmpts
	to parse the entire string again.
	(path::_M_append(string_type)): Likewise.
	(path::operator+=(const path&)): Likewise.
	(path::_M_concat(string_type)): Likewise.
	(path::remove_filename()): Perform trim directly instead of calling
	(path::_M_split_cmpts()): Rewrite in terms of _Parser class.
	(path::_M_trim, path::_M_add_root_name, path::_M_add_root_dir)
	(path::_M_add_filename): Remove.

Tested x86_64-linux. I intend to commit this to trunk tomorrow.

There are some other performance improvements that could be made to
the std::filesystem implementation, but this is the main thing I
wanted to do for PR 71044.

Attachment: patch.txt
Description: Text document

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]