Browse Source

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.
Ben Boeckel 8 years ago
parent
commit
c0e7a13702
1 changed files with 99 additions and 49 deletions
  1. 99 49
      Source/cmAddCustomCommandCommand.cxx

+ 99 - 49
Source/cmAddCustomCommandCommand.cxx

@@ -3,6 +3,7 @@
 #include "cmAddCustomCommandCommand.h"
 
 #include <sstream>
+#include <unordered_set>
 #include <utility>
 
 #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<std::string> 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;