Skip to content

Commit 4873e21

Browse files
committed
Optimization: Use only one regex
1 parent 3efa878 commit 4873e21

File tree

2 files changed

+52
-52
lines changed

2 files changed

+52
-52
lines changed

include/openPMD/CustomHierarchy.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ namespace internal
5252
* @todo: When reading, maybe compile all regexes into one big regex
5353
* for performance?
5454
*/
55-
std::map<std::string, std::regex> meshesPath;
56-
std::map<std::string, std::regex> particlesPath;
55+
std::regex meshRegex;
56+
std::set<std::string> collectNewMeshesPaths;
57+
std::regex particleRegex;
58+
std::set<std::string> collectNewParticlesPaths;
5759

5860
/*
5961
* These values decide which path will be returned upon use of the

src/CustomHierarchy.cpp

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <initializer_list>
3636
#include <iterator>
3737
#include <memory>
38+
#include <numeric>
3839
#include <optional>
3940
#include <regex>
4041
#include <sstream>
@@ -119,7 +120,7 @@ namespace internal
119120
namespace
120121
{
121122
bool anyPathRegexMatches(
122-
std::map<std::string, std::regex> regexes,
123+
std::regex regex,
123124
std::vector<std::string> const &path,
124125
std::string const &name)
125126
{
@@ -150,16 +151,10 @@ namespace internal
150151
pathsToMatch.emplace_back(*path.rbegin() + "/");
151152
}
152153
return std::any_of(
153-
regexes.begin(),
154-
regexes.end(),
155-
[&pathsToMatch](auto const &regex) {
156-
return std::any_of(
157-
pathsToMatch.begin(),
158-
pathsToMatch.end(),
159-
[&regex](std::string const &candidate_path) {
160-
return std::regex_match(
161-
candidate_path, regex.second);
162-
});
154+
pathsToMatch.begin(),
155+
pathsToMatch.end(),
156+
[&regex](std::string const &candidate_path) {
157+
return std::regex_match(candidate_path, regex);
163158
});
164159
}
165160
} // namespace
@@ -169,20 +164,29 @@ namespace internal
169164
std::vector<std::string> const &particles)
170165
{
171166
std::regex is_default_path_specification("[[:alnum:]_]+/", regex_flags);
172-
for (auto [deque, vec] :
173-
{std::make_tuple(&this->meshesPath, &meshes),
174-
std::make_tuple(&this->particlesPath, &particles)})
167+
for (auto [target_regex, vec] :
168+
{std::make_tuple(&this->meshRegex, &meshes),
169+
std::make_tuple(&this->particleRegex, &particles)})
175170
{
176-
std::transform(
177-
vec->begin(),
178-
vec->end(),
179-
std::inserter(*deque, deque->begin()),
180-
[](auto const &str) {
181-
return std::make_pair(
182-
str,
183-
std::regex(
184-
str, regex_flags | std::regex_constants::optimize));
185-
});
171+
if (vec->empty())
172+
{
173+
*target_regex = std::regex(
174+
/* does not match anything */ "a^",
175+
regex_flags | std::regex_constants::optimize);
176+
continue;
177+
}
178+
auto begin = vec->begin();
179+
std::stringstream build_regex;
180+
build_regex << '(' << *begin++ << ')';
181+
for (; begin != vec->end(); ++begin)
182+
{
183+
build_regex << "|(" << *begin << ')';
184+
}
185+
auto regex_string = build_regex.str();
186+
// std::cout << "Using regex string: " << regex_string << std::endl;
187+
*target_regex = std::regex(
188+
std::move(regex_string),
189+
regex_flags | std::regex_constants::optimize);
186190
}
187191
setDefaultMeshesParticlesPath(meshes, particles, *this);
188192
}
@@ -207,12 +211,12 @@ namespace internal
207211
bool MeshesParticlesPath::isParticle(
208212
std::vector<std::string> const &path, std::string const &name) const
209213
{
210-
return anyPathRegexMatches(particlesPath, path, name);
214+
return anyPathRegexMatches(particleRegex, path, name);
211215
}
212216
bool MeshesParticlesPath::isMesh(
213217
std::vector<std::string> const &path, std::string const &name) const
214218
{
215-
return anyPathRegexMatches(meshesPath, path, name);
219+
return anyPathRegexMatches(meshRegex, path, name);
216220
}
217221

218222
CustomHierarchyData::CustomHierarchyData()
@@ -524,9 +528,7 @@ void CustomHierarchy::flush_internal(
524528
: concatWithSep(currentPath, "/") + "/") +
525529
name;
526530
}
527-
mpp.meshesPath.emplace(
528-
extend_meshes_path,
529-
std::regex(extend_meshes_path, regex_flags));
531+
mpp.collectNewMeshesPaths.emplace(std::move(extend_meshes_path));
530532
}
531533
mesh.flush(name, flushParams);
532534
}
@@ -549,9 +551,8 @@ void CustomHierarchy::flush_internal(
549551
: concatWithSep(currentPath, "/") + "/") +
550552
name;
551553
}
552-
mpp.particlesPath.emplace(
553-
extend_particles_path,
554-
std::regex(extend_particles_path, regex_flags));
554+
mpp.collectNewParticlesPaths.emplace(
555+
std::move(extend_particles_path));
555556
}
556557
particleSpecies.flush(name, flushParams);
557558
}
@@ -570,28 +571,25 @@ void CustomHierarchy::flush(
570571
*/
571572

572573
Series s = this->retrieveSeries();
573-
internal::MeshesParticlesPath mpp(s.meshesPaths(), s.particlesPaths());
574-
auto num_meshes_paths = mpp.meshesPath.size();
575-
auto num_particles_paths = mpp.particlesPath.size();
574+
std::vector<std::string> meshesPaths = s.meshesPaths(),
575+
particlesPaths = s.particlesPaths();
576+
internal::MeshesParticlesPath mpp(meshesPaths, particlesPaths);
576577
std::vector<std::string> currentPath;
577578
flush_internal(flushParams, mpp, currentPath);
578-
std::vector<std::string> meshesPaths, particlesPaths;
579-
for (auto [map, vec] :
580-
{std::make_pair(&mpp.meshesPath, &meshesPaths),
581-
std::make_pair(&mpp.particlesPath, &particlesPaths)})
582-
{
583-
std::transform(
584-
map->begin(),
585-
map->end(),
586-
std::back_inserter(*vec),
587-
[](auto const &pair) { return pair.first; });
588-
}
589-
if (meshesPaths.size() > num_meshes_paths)
579+
if (!mpp.collectNewMeshesPaths.empty() ||
580+
!mpp.collectNewParticlesPaths.empty())
590581
{
582+
for (auto [newly_added_paths, vec] :
583+
{std::make_pair(&mpp.collectNewMeshesPaths, &meshesPaths),
584+
std::make_pair(&mpp.collectNewParticlesPaths, &particlesPaths)})
585+
{
586+
std::transform(
587+
newly_added_paths->begin(),
588+
newly_added_paths->end(),
589+
std::back_inserter(*vec),
590+
[](auto const &pair) { return pair; });
591+
}
591592
s.setMeshesPath(meshesPaths);
592-
}
593-
if (particlesPaths.size() > num_particles_paths)
594-
{
595593
s.setParticlesPath(particlesPaths);
596594
}
597595
}

0 commit comments

Comments
 (0)