From d5de9402ee22eea985d6842baafd8922e15d3784 Mon Sep 17 00:00:00 2001 From: BreadFish64 Date: Tue, 5 Dec 2023 23:17:19 -0500 Subject: Improve path splitting speed --- src/common/fs/path_util.cpp | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'src/common/fs/path_util.cpp') diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp index c3a81f9a9..d2f50432a 100644 --- a/src/common/fs/path_util.cpp +++ b/src/common/fs/path_util.cpp @@ -354,18 +354,36 @@ std::string_view RemoveTrailingSlash(std::string_view path) { return path; } -std::vector SplitPathComponents(std::string_view filename) { - std::string copy(filename); - std::replace(copy.begin(), copy.end(), '\\', '/'); - std::vector out; - - std::stringstream stream(copy); - std::string item; - while (std::getline(stream, item, '/')) { - out.push_back(std::move(item)); +template +static void ForEachPathComponent(std::string_view filename, F&& cb) { + const char* component_begin = filename.data(); + const char* const end = component_begin + filename.size(); + for (const char* it = component_begin; it != end; ++it) { + const char c = *it; + if (c == '\\' || c == '/') { + if (component_begin != it) { + cb(std::string_view{component_begin, it}); + } + component_begin = it + 1; + } } + if (component_begin != end) { + cb(std::string_view{component_begin, end}); + } +} + +std::vector SplitPathComponents(std::string_view filename) { + std::vector components; + ForEachPathComponent(filename, [&](auto component) { components.emplace_back(component); }); + + return components; +} + +std::vector SplitPathComponentsCopy(std::string_view filename) { + std::vector components; + ForEachPathComponent(filename, [&](auto component) { components.emplace_back(component); }); - return out; + return components; } std::string SanitizePath(std::string_view path_, DirectorySeparator directory_separator) { -- cgit v1.2.3