util: add a tokenize_string() overload which returns string_views

Additionally, it uses a single "char" as delimiter, which is also
faster.

This patch speeds up Zeek startup by 10%.
This commit is contained in:
Max Kellermann 2020-01-31 12:25:48 +01:00
parent 763afe6f5f
commit 26da10ca05
2 changed files with 24 additions and 6 deletions

View file

@ -837,8 +837,7 @@ bool ensure_intermediate_dirs(const char* dirname)
bool absolute = dirname[0] == '/'; bool absolute = dirname[0] == '/';
string path = normalize_path(dirname); string path = normalize_path(dirname);
vector<string> path_components; const auto path_components = tokenize_string(path, '/');
tokenize_string(path, "/", &path_components);
string current_dir; string current_dir;
@ -1525,6 +1524,25 @@ vector<string>* tokenize_string(const std::string_view input, const std::string_
return rval; return rval;
} }
vector<std::string_view> tokenize_string(const std::string_view input, const char delim) noexcept
{
vector<std::string_view> rval;
size_t pos = 0;
size_t n;
auto found = 0;
while ( (n = input.find(delim, pos)) != string::npos )
{
++found;
rval.push_back(input.substr(pos, n - pos));
pos = n + 1;
}
rval.push_back(input.substr(pos));
return rval;
}
TEST_CASE("util normalize_path") TEST_CASE("util normalize_path")
{ {
CHECK(normalize_path("/1/2/3") == "/1/2/3"); CHECK(normalize_path("/1/2/3") == "/1/2/3");
@ -1555,7 +1573,6 @@ TEST_CASE("util normalize_path")
string normalize_path(const std::string_view path) string normalize_path(const std::string_view path)
{ {
size_t n; size_t n;
vector<string> components;
vector<std::string_view> final_components; vector<std::string_view> final_components;
string new_path; string new_path;
new_path.reserve(path.size()); new_path.reserve(path.size());
@ -1563,7 +1580,7 @@ string normalize_path(const std::string_view path)
if ( !path.empty() && path[0] == '/' ) if ( !path.empty() && path[0] == '/' )
new_path = "/"; new_path = "/";
tokenize_string(path, "/", &components); const auto components = tokenize_string(path, '/');
final_components.reserve(components.size()); final_components.reserve(components.size());
for ( auto it = components.begin(); it != components.end(); ++it ) for ( auto it = components.begin(); it != components.end(); ++it )
@ -1616,8 +1633,7 @@ string without_bropath_component(const string& path)
{ {
string rval = normalize_path(path); string rval = normalize_path(path);
vector<string> paths; const auto paths = tokenize_string(bro_path(), ':');
tokenize_string(bro_path(), ":", &paths);
for ( size_t i = 0; i < paths.size(); ++i ) for ( size_t i = 0; i < paths.size(); ++i )
{ {

View file

@ -150,6 +150,8 @@ std::vector<std::string>* tokenize_string(std::string_view input,
std::string_view delim, std::string_view delim,
std::vector<std::string>* rval = 0, int limit = 0); std::vector<std::string>* rval = 0, int limit = 0);
std::vector<std::string_view> tokenize_string(const std::string_view input, const char delim) noexcept;
extern char* copy_string(const char* s); extern char* copy_string(const char* s);
extern int streq(const char* s1, const char* s2); extern int streq(const char* s1, const char* s2);