From c0e7a137025789c41349ae0935609e7bd083587a Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Tue, 23 Jan 2018 18:29:13 -0500 Subject: cmAddCustomCommandCommand: store keywords in strings Callgrind indicated that `strlen` was being called a lot of times here due to the string comparisons. Since keywords are "sparse" in `add_custom_command`, use a hash comparison to handle keywords and then use strings for comparison since they have a built-in length parameter. --- Source/cmAddCustomCommandCommand.cxx | 148 +++++++++++++++++++++++------------ 1 file changed, 99 insertions(+), 49 deletions(-) diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index 14dfdae..3186583 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -3,6 +3,7 @@ #include "cmAddCustomCommandCommand.h" #include +#include #include #include "cmCustomCommand.h" @@ -69,57 +70,106 @@ bool cmAddCustomCommandCommand::InitialPass( tdoing doing = doing_nothing; +#define MAKE_STATIC_KEYWORD(KEYWORD) \ + static const std::string key##KEYWORD = #KEYWORD + MAKE_STATIC_KEYWORD(APPEND); + MAKE_STATIC_KEYWORD(ARGS); + MAKE_STATIC_KEYWORD(BYPRODUCTS); + MAKE_STATIC_KEYWORD(COMMAND); + MAKE_STATIC_KEYWORD(COMMAND_EXPAND_LISTS); + MAKE_STATIC_KEYWORD(COMMENT); + MAKE_STATIC_KEYWORD(DEPENDS); + MAKE_STATIC_KEYWORD(DEPFILE); + MAKE_STATIC_KEYWORD(IMPLICIT_DEPENDS); + MAKE_STATIC_KEYWORD(MAIN_DEPENDENCY); + MAKE_STATIC_KEYWORD(OUTPUT); + MAKE_STATIC_KEYWORD(OUTPUTS); + MAKE_STATIC_KEYWORD(POST_BUILD); + MAKE_STATIC_KEYWORD(PRE_BUILD); + MAKE_STATIC_KEYWORD(PRE_LINK); + MAKE_STATIC_KEYWORD(SOURCE); + MAKE_STATIC_KEYWORD(TARGET); + MAKE_STATIC_KEYWORD(USES_TERMINAL); + MAKE_STATIC_KEYWORD(VERBATIM); + MAKE_STATIC_KEYWORD(WORKING_DIRECTORY); +#undef MAKE_STATIC_KEYWORD + static std::unordered_set keywords; + if (keywords.empty()) { + keywords.insert(keyAPPEND); + keywords.insert(keyARGS); + keywords.insert(keyBYPRODUCTS); + keywords.insert(keyCOMMAND); + keywords.insert(keyCOMMAND_EXPAND_LISTS); + keywords.insert(keyCOMMENT); + keywords.insert(keyDEPENDS); + keywords.insert(keyDEPFILE); + keywords.insert(keyIMPLICIT_DEPENDS); + keywords.insert(keyMAIN_DEPENDENCY); + keywords.insert(keyOUTPUT); + keywords.insert(keyOUTPUTS); + keywords.insert(keyPOST_BUILD); + keywords.insert(keyPRE_BUILD); + keywords.insert(keyPRE_LINK); + keywords.insert(keySOURCE); + keywords.insert(keyTARGET); + keywords.insert(keyUSES_TERMINAL); + keywords.insert(keyVERBATIM); + keywords.insert(keyWORKING_DIRECTORY); + } + for (std::string const& copy : args) { - if (copy == "SOURCE") { - doing = doing_source; - } else if (copy == "COMMAND") { - doing = doing_command; + if (keywords.count(copy)) { + if (copy == keySOURCE) { + doing = doing_source; + } else if (copy == keyCOMMAND) { + doing = doing_command; - // Save the current command before starting the next command. - if (!currentLine.empty()) { - commandLines.push_back(currentLine); - currentLine.clear(); - } - } else if (copy == "PRE_BUILD") { - cctype = cmTarget::PRE_BUILD; - } else if (copy == "PRE_LINK") { - cctype = cmTarget::PRE_LINK; - } else if (copy == "POST_BUILD") { - cctype = cmTarget::POST_BUILD; - } else if (copy == "VERBATIM") { - verbatim = true; - } else if (copy == "APPEND") { - append = true; - } else if (copy == "USES_TERMINAL") { - uses_terminal = true; - } else if (copy == "COMMAND_EXPAND_LISTS") { - command_expand_lists = true; - } else if (copy == "TARGET") { - doing = doing_target; - } else if (copy == "ARGS") { - // Ignore this old keyword. - } else if (copy == "DEPENDS") { - doing = doing_depends; - } else if (copy == "OUTPUTS") { - doing = doing_outputs; - } else if (copy == "OUTPUT") { - doing = doing_output; - } else if (copy == "BYPRODUCTS") { - doing = doing_byproducts; - } else if (copy == "WORKING_DIRECTORY") { - doing = doing_working_directory; - } else if (copy == "MAIN_DEPENDENCY") { - doing = doing_main_dependency; - } else if (copy == "IMPLICIT_DEPENDS") { - doing = doing_implicit_depends_lang; - } else if (copy == "COMMENT") { - doing = doing_comment; - } else if (copy == "DEPFILE") { - doing = doing_depfile; - if (this->Makefile->GetGlobalGenerator()->GetName() != "Ninja") { - this->SetError("Option DEPFILE not supported by " + - this->Makefile->GetGlobalGenerator()->GetName()); - return false; + // Save the current command before starting the next command. + if (!currentLine.empty()) { + commandLines.push_back(currentLine); + currentLine.clear(); + } + } else if (copy == keyPRE_BUILD) { + cctype = cmTarget::PRE_BUILD; + } else if (copy == keyPRE_LINK) { + cctype = cmTarget::PRE_LINK; + } else if (copy == keyPOST_BUILD) { + cctype = cmTarget::POST_BUILD; + } else if (copy == keyVERBATIM) { + verbatim = true; + } else if (copy == keyAPPEND) { + append = true; + } else if (copy == keyUSES_TERMINAL) { + uses_terminal = true; + } else if (copy == keyCOMMAND_EXPAND_LISTS) { + command_expand_lists = true; + } else if (copy == keyTARGET) { + doing = doing_target; + } else if (copy == keyARGS) { + // Ignore this old keyword. + } else if (copy == keyDEPENDS) { + doing = doing_depends; + } else if (copy == keyOUTPUTS) { + doing = doing_outputs; + } else if (copy == keyOUTPUT) { + doing = doing_output; + } else if (copy == keyBYPRODUCTS) { + doing = doing_byproducts; + } else if (copy == keyWORKING_DIRECTORY) { + doing = doing_working_directory; + } else if (copy == keyMAIN_DEPENDENCY) { + doing = doing_main_dependency; + } else if (copy == keyIMPLICIT_DEPENDS) { + doing = doing_implicit_depends_lang; + } else if (copy == keyCOMMENT) { + doing = doing_comment; + } else if (copy == keyDEPFILE) { + doing = doing_depfile; + if (this->Makefile->GetGlobalGenerator()->GetName() != "Ninja") { + this->SetError("Option DEPFILE not supported by " + + this->Makefile->GetGlobalGenerator()->GetName()); + return false; + } } } else { std::string filename; -- cgit v0.12