From 4a6073cedb494f5cfc879888593156fbc0482f1e Mon Sep 17 00:00:00 2001 From: "Abele, Daniel" Date: Fri, 8 Dec 2023 11:52:20 +0100 Subject: [PATCH] perf: bitset of age groups check num age groups when creating the world --- cpp/models/abm/config.h | 36 +++++++++++++++++++++++++++++ cpp/models/abm/testing_strategy.cpp | 8 +++---- cpp/models/abm/testing_strategy.h | 3 ++- cpp/models/abm/world.h | 4 +++- 4 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 cpp/models/abm/config.h diff --git a/cpp/models/abm/config.h b/cpp/models/abm/config.h new file mode 100644 index 0000000000..5f281331ec --- /dev/null +++ b/cpp/models/abm/config.h @@ -0,0 +1,36 @@ +/* +* Copyright (C) 2020-2024 MEmilio +* +* Authors: Daniel Abele +* +* Contact: Martin J. Kuehn +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef MIO_ABM_CONFIG_H +#define MIO_ABM_CONFIG_H + +namespace mio +{ +namespace abm +{ + +/** + * Maximum number of age groups allowed in the model. + */ +const constexpr int MAX_NUM_AGE_GROUPS = 64; + +} +} // namespace mio + +#endif diff --git a/cpp/models/abm/testing_strategy.cpp b/cpp/models/abm/testing_strategy.cpp index fc7c06d724..2fce3d2b17 100644 --- a/cpp/models/abm/testing_strategy.cpp +++ b/cpp/models/abm/testing_strategy.cpp @@ -29,7 +29,7 @@ namespace abm TestingCriteria::TestingCriteria(const std::vector& ages, const std::vector& infection_states) { for (auto age : ages) { - m_ages.insert(static_cast(age)); + m_ages.set(static_cast(age), true); } for (auto infection_state : infection_states) { m_infection_states.set(static_cast(infection_state), true); @@ -43,12 +43,12 @@ bool TestingCriteria::operator==(const TestingCriteria& other) const void TestingCriteria::add_age_group(const AgeGroup age_group) { - m_ages.insert(static_cast(age_group)); + m_ages.set(static_cast(age_group), true); } void TestingCriteria::remove_age_group(const AgeGroup age_group) { - m_ages.erase(static_cast(age_group)); + m_ages.set(static_cast(age_group), false); } void TestingCriteria::add_infection_state(const InfectionState infection_state) @@ -64,7 +64,7 @@ void TestingCriteria::remove_infection_state(const InfectionState infection_stat bool TestingCriteria::evaluate(const Person& p, TimePoint t) const { // An empty vector of ages or none bitset of #InfectionStates% means that no condition on the corresponding property is set. - return (m_ages.empty() || m_ages.count(static_cast(p.get_age()))) && + return (m_ages.none() || m_ages[static_cast(p.get_age())]) && (m_infection_states.none() || m_infection_states[static_cast(p.get_infection_state(t))]); } diff --git a/cpp/models/abm/testing_strategy.h b/cpp/models/abm/testing_strategy.h index cc41736876..e947ec30c7 100644 --- a/cpp/models/abm/testing_strategy.h +++ b/cpp/models/abm/testing_strategy.h @@ -20,6 +20,7 @@ #ifndef EPI_ABM_TESTING_SCHEME_H #define EPI_ABM_TESTING_SCHEME_H +#include "abm/config.h" #include "abm/parameters.h" #include "abm/person.h" #include "abm/location.h" @@ -91,7 +92,7 @@ class TestingCriteria bool evaluate(const Person& p, TimePoint t) const; private: - std::unordered_set m_ages; ///< Set of #AgeGroup%s that are either allowed or required to be tested. + std::bitset m_ages; ///< Set of #AgeGroup%s that are either allowed or required to be tested. std::bitset<(size_t)InfectionState::Count> m_infection_states; /**< BitSet of #InfectionState%s that are either allowed or required to be tested.*/ diff --git a/cpp/models/abm/world.h b/cpp/models/abm/world.h index 52f41bad7f..8aa65ac5de 100644 --- a/cpp/models/abm/world.h +++ b/cpp/models/abm/world.h @@ -20,6 +20,7 @@ #ifndef EPI_ABM_WORLD_H #define EPI_ABM_WORLD_H +#include "abm/config.h" #include "abm/location_type.h" #include "abm/parameters.h" #include "abm/location.h" @@ -55,7 +56,7 @@ class World /** * @brief Create a World. - * @param[in] num_agegroups The number of AgeGroup%s in the simulated World. + * @param[in] num_agegroups The number of AgeGroup%s in the simulated World. Must be less than MAX_NUM_AGE_GROUPS. */ World(size_t num_agegroups) : parameters(num_agegroups) @@ -63,6 +64,7 @@ class World , m_use_migration_rules(true) , m_cemetery_id(add_location(LocationType::Cemetery)) { + assert(num_agegroups < MAX_NUM_AGE_GROUPS && "MAX_NUM_AGE_GROUPS exceeded."); } /**