From d02fbcf282768d4d7943fc18039b1d981b6f2162 Mon Sep 17 00:00:00 2001 From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com> Date: Sat, 21 Dec 2024 17:31:19 +0000 Subject: [PATCH] fix performance regression caused by #32 the issue isn't with the pr itself, however it did expose the lack of caching with the translation strings, it will continue to search for strings, even if we already found them. to solve this, i used a map to cache said strings --- sphaira/source/i18n.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/sphaira/source/i18n.cpp b/sphaira/source/i18n.cpp index c50a4ad..a97151b 100644 --- a/sphaira/source/i18n.cpp +++ b/sphaira/source/i18n.cpp @@ -3,6 +3,7 @@ #include "log.hpp" #include #include +#include namespace sphaira::i18n { namespace { @@ -10,32 +11,46 @@ namespace { std::vector g_i18n_data; yyjson_doc* json; yyjson_val* root; +std::unordered_map g_tr_cache; std::string get_internal(const char* str, size_t len) { + const std::string kkey = {str, len}; + + if (auto it = g_tr_cache.find(kkey); it != g_tr_cache.end()) { + return it->second; + } + + // add default entry + g_tr_cache.emplace(kkey, kkey); + if (!json || !root) { log_write("no json or root\n"); - return str; + return kkey; } auto key = yyjson_obj_getn(root, str, len); if (!key) { - log_write("\tfailed to find key: [%.*s]\n", len, str); - return str; + log_write("\tfailed to find key: [%s]\n", kkey.c_str()); + return kkey; } auto val = yyjson_get_str(key); auto val_len = yyjson_get_len(key); if (!val || !val_len) { - log_write("\tfailed to get value: [%.*s]\n", len, str); - return str; + log_write("\tfailed to get value: [%s]\n", kkey.c_str()); + return kkey; } - return {val, val_len}; + // update entry in cache + const std::string ret = {val, val_len}; + g_tr_cache.insert_or_assign(kkey, ret); + return ret; } } // namespace bool init(long index) { + g_tr_cache.clear(); R_TRY_RESULT(romfsInit(), false); ON_SCOPE_EXIT( romfsExit() );