Skip to content

Commit 91deb37

Browse files
authored
perf: configmanager cache (opentibiabr#3232)
This introduces a performance enhancement by implementing a cache within the ConfigManager. This change reduces the overhead associated with accessing standard configuration variables, leading to more efficient retrieval and improved overall performance.
1 parent c53eed6 commit 91deb37

2 files changed

Lines changed: 63 additions & 11 deletions

File tree

src/config/configmanager.cpp

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,10 @@ bool ConfigManager::load() {
373373
}
374374

375375
bool ConfigManager::reload() {
376+
m_configString.clear();
377+
m_configInteger.clear();
378+
m_configBoolean.clear();
379+
m_configFloat.clear();
376380
const bool result = load();
377381
if (transformToSHA1(getString(SERVER_MOTD)) != g_game().getMotdHash()) {
378382
g_game().incrementMotdNum();
@@ -437,34 +441,77 @@ float ConfigManager::loadFloatConfig(lua_State* L, const ConfigKey_t &key, const
437441
}
438442

439443
const std::string &ConfigManager::getString(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
440-
static const std::string dummyStr;
441-
if (configs.contains(key) && std::holds_alternative<std::string>(configs.at(key))) {
442-
return std::get<std::string>(configs.at(key));
444+
auto itCache = m_configString.find(key);
445+
if (itCache != m_configString.end()) {
446+
return itCache->second;
443447
}
448+
449+
auto it = configs.find(key);
450+
if (it != configs.end()) {
451+
if (const auto* value = std::get_if<std::string>(&it->second)) {
452+
m_configString[key] = *value;
453+
return *value;
454+
}
455+
}
456+
457+
static const std::string staticEmptyString;
444458
g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
445-
return dummyStr;
459+
return staticEmptyString;
446460
}
447461

448462
int32_t ConfigManager::getNumber(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
449-
if (configs.contains(key) && std::holds_alternative<int32_t>(configs.at(key))) {
450-
return std::get<int32_t>(configs.at(key));
463+
auto itCache = m_configInteger.find(key);
464+
if (itCache != m_configInteger.end()) {
465+
return itCache->second;
451466
}
467+
468+
auto it = configs.find(key);
469+
if (it != configs.end()) {
470+
if (std::holds_alternative<int32_t>(it->second)) {
471+
const auto value = std::get<int32_t>(it->second);
472+
m_configInteger[key] = value;
473+
return value;
474+
}
475+
}
476+
452477
g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
453478
return 0;
454479
}
455480

456481
bool ConfigManager::getBoolean(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
457-
if (configs.contains(key) && std::holds_alternative<bool>(configs.at(key))) {
458-
return std::get<bool>(configs.at(key));
482+
auto itCache = m_configBoolean.find(key);
483+
if (itCache != m_configBoolean.end()) {
484+
return itCache->second;
459485
}
486+
487+
auto it = configs.find(key);
488+
if (it != configs.end()) {
489+
if (std::holds_alternative<bool>(it->second)) {
490+
const auto value = std::get<bool>(it->second);
491+
m_configBoolean[key] = value;
492+
return value;
493+
}
494+
}
495+
460496
g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
461497
return false;
462498
}
463499

464500
float ConfigManager::getFloat(const ConfigKey_t &key, const std::source_location &location /*= std::source_location::current()*/) const {
465-
if (configs.contains(key) && std::holds_alternative<float>(configs.at(key))) {
466-
return std::get<float>(configs.at(key));
501+
auto itCache = m_configFloat.find(key);
502+
if (itCache != m_configFloat.end()) {
503+
return itCache->second;
467504
}
505+
506+
auto it = configs.find(key);
507+
if (it != configs.end()) {
508+
if (std::holds_alternative<float>(it->second)) {
509+
const auto value = std::get<float>(it->second);
510+
m_configFloat[key] = value;
511+
return value;
512+
}
513+
}
514+
468515
g_logger().warn("[{}] accessing invalid or wrong type index: {}[{}]. Called line: {}:{}, in {}", __FUNCTION__, magic_enum::enum_name(key), fmt::underlying(key), location.line(), location.column(), location.function_name());
469516
return 0.0f;
470517
}

src/config/configmanager.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ class ConfigManager {
4242
[[nodiscard]] float getFloat(const ConfigKey_t &key, const std::source_location &location = std::source_location::current()) const;
4343

4444
private:
45-
phmap::flat_hash_map<ConfigKey_t, ConfigValue> configs;
45+
mutable std::unordered_map<ConfigKey_t, std::string> m_configString;
46+
mutable std::unordered_map<ConfigKey_t, bool> m_configBoolean;
47+
mutable std::unordered_map<ConfigKey_t, int32_t> m_configInteger;
48+
mutable std::unordered_map<ConfigKey_t, float> m_configFloat;
49+
50+
std::unordered_map<ConfigKey_t, ConfigValue> configs;
4651
std::string loadStringConfig(lua_State* L, const ConfigKey_t &key, const char* identifier, const std::string &defaultValue);
4752
int32_t loadIntConfig(lua_State* L, const ConfigKey_t &key, const char* identifier, const int32_t &defaultValue);
4853
bool loadBoolConfig(lua_State* L, const ConfigKey_t &key, const char* identifier, const bool &defaultValue);

0 commit comments

Comments
 (0)