From 6a263ba026cde4efee734195a96ae0b2ca0bbcb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Wed, 16 Aug 2023 11:10:38 +0200 Subject: [PATCH] optimized `Library::detectContainerInternal()` a bit (#5333) Scanning `cli/filelister.cpp` with `DISABLE_VALUEFLOW=1` and `--enable=all -Ilib -D__GNUC__` Clang 15 `111,300,996` -> `106,883,955` GCC 13 `110,555,879` -> `105,983,608` --- lib/library.cpp | 42 +++++++++++++++++++++++++----------------- lib/library.h | 2 +- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/lib/library.cpp b/lib/library.cpp index 4142dcd8a..15d649171 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -419,7 +419,7 @@ Library::Error Library::load(const tinyxml2::XMLDocument &doc) const char* const inherits = node->Attribute("inherits"); if (inherits) { - const std::map::const_iterator i = containers.find(inherits); + const std::unordered_map::const_iterator i = containers.find(inherits); if (i != containers.end()) container = i->second; // Take values from parent and overwrite them if necessary else @@ -1158,8 +1158,17 @@ bool Library::isScopeNoReturn(const Token *end, std::string *unknownFunc) const return false; } -const Library::Container* Library::detectContainerInternal(const Token* typeStart, DetectContainer detect, bool* isIterator, bool withoutStd) const +const Library::Container* Library::detectContainerInternal(const Token* const typeStart, DetectContainer detect, bool* isIterator, bool withoutStd) const { + const Token* firstLinkedTok = nullptr; + for (const Token* tok = typeStart; tok && !tok->varId(); tok = tok->next()) { + if (!tok->link()) + continue; + + firstLinkedTok = tok; + break; + } + for (const std::pair & c : containers) { const Container& container = c.second; if (container.startPattern.empty()) @@ -1177,23 +1186,22 @@ const Library::Container* Library::detectContainerInternal(const Token* typeStar return &container; } - for (const Token* tok = typeStart; tok && !tok->varId(); tok = tok->next()) { - if (!tok->link()) - continue; + if (!firstLinkedTok) + continue; - const bool matchedStartPattern = Token::Match(typeStart, container.startPattern2.c_str() + offset); + const bool matchedStartPattern = Token::Match(typeStart, container.startPattern2.c_str() + offset); + if (!matchedStartPattern) + continue; - if (detect != ContainerOnly && matchedStartPattern && Token::Match(tok->link(), container.itEndPattern.c_str())) { - if (isIterator) - *isIterator = true; - return &container; - } - if (detect != IteratorOnly && matchedStartPattern && Token::Match(tok->link(), container.endPattern.c_str())) { - if (isIterator) - *isIterator = false; - return &container; - } - break; + if (detect != ContainerOnly && Token::Match(firstLinkedTok->link(), container.itEndPattern.c_str())) { + if (isIterator) + *isIterator = true; + return &container; + } + if (detect != IteratorOnly && Token::Match(firstLinkedTok->link(), container.endPattern.c_str())) { + if (isIterator) + *isIterator = false; + return &container; } } return nullptr; diff --git a/lib/library.h b/lib/library.h index 300382d9f..9c1b060f9 100644 --- a/lib/library.h +++ b/lib/library.h @@ -282,7 +282,7 @@ public: static Yield yieldFrom(const std::string& yieldName); static Action actionFrom(const std::string& actionName); }; - std::map containers; + std::unordered_map containers; const Container* detectContainer(const Token* typeStart) const; const Container* detectIterator(const Token* typeStart) const; const Container* detectContainerOrIterator(const Token* typeStart, bool* isIterator = nullptr, bool withoutStd = false) const;