From 97286e13bd47c651444d1d6f9a3896537fc33787 Mon Sep 17 00:00:00 2001 From: Tomas Rapkauskas Date: Fri, 1 May 2015 20:36:08 +0300 Subject: [PATCH] Speed up finding message catalog by name in wxTranslations. Use a helper hash map to allow efficiently finding message catalogs by name instead of using linear search in a linked list which can be noticeably slow when many catalogs are used. This speeds up wxGetTranslation() when the domain is specified. Closes #16975. --- include/wx/translation.h | 6 ++++++ src/common/translation.cpp | 14 +++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/wx/translation.h b/include/wx/translation.h index 5c5761d440..2ca62cf4cc 100644 --- a/include/wx/translation.h +++ b/include/wx/translation.h @@ -183,6 +183,12 @@ private: wxTranslationsLoader *m_loader; wxMsgCatalog *m_pMsgCat; // pointer to linked list of catalogs + + // In addition to keeping all the catalogs in the linked list, we also + // store them in a hash map indexed by the domain name to allow finding + // them by name efficiently. + WX_DECLARE_HASH_MAP(wxString, wxMsgCatalog *, wxStringHash, wxStringEqual, wxMsgCatalogMap); + wxMsgCatalogMap m_catalogMap; }; diff --git a/src/common/translation.cpp b/src/common/translation.cpp index fde7cdc585..bc0717fa73 100644 --- a/src/common/translation.cpp +++ b/src/common/translation.cpp @@ -1573,8 +1573,10 @@ bool wxTranslations::LoadCatalog(const wxString& domain, const wxString& lang, c { // add it to the head of the list so that in GetString it will // be searched before the catalogs added earlier + cat->m_pNext = m_pMsgCat; m_pMsgCat = cat; + m_catalogMap[domain] = cat; return true; } @@ -1735,18 +1737,12 @@ wxString wxTranslations::GetHeaderValue(const wxString& header, } -// find catalog by name in a linked list, return NULL if !found +// find catalog by name wxMsgCatalog *wxTranslations::FindCatalog(const wxString& domain) const { - // linear search in the linked list - wxMsgCatalog *pMsgCat; - for ( pMsgCat = m_pMsgCat; pMsgCat != NULL; pMsgCat = pMsgCat->m_pNext ) - { - if ( pMsgCat->GetDomain() == domain ) - return pMsgCat; - } + const wxMsgCatalogMap::const_iterator found = m_catalogMap.find(domain); - return NULL; + return found == m_catalogMap.end() ? NULL : found->second; } // ----------------------------------------------------------------------------