optimize IsIdentChar
authorEvan Martin <martine@danga.com>
Fri, 9 Sep 2011 22:52:36 +0000 (15:52 -0700)
committerEvan Martin <martine@danga.com>
Fri, 9 Sep 2011 22:52:36 +0000 (15:52 -0700)
Rather than nested tests, use a table.  Shaves 200ms off Chrome null startup.

src/parsers.cc

index 35790b2..849a3e1 100644 (file)
@@ -102,12 +102,32 @@ bool Tokenizer::Newline(string* err) {
   return true;
 }
 
+/// Return true if |c| is part of an identifier.
 static bool IsIdentChar(char c) {
-  return
-    ('a' <= c && c <= 'z') ||
-    ('+' <= c && c <= '9') ||  // +,-./ and numbers
-    ('A' <= c && c <= 'Z') ||
-    (c == '_') || (c == '$') || (c == '\\');
+  // This function shows up hot on profiles.  Instead of the natural
+  // 'if' statement, use a table as generated by this Python script:
+  //    import string
+  //    cs = set()
+  //    for c in string.ascii_letters + string.digits + r'+,-./\_$':
+  //        cs.add(ord(c))
+  //    for i in range(128):
+  //        if i in cs:
+  //            print '1,',
+  //        else:
+  //            print '0,',
+  //        if i % 16 == 15:
+  //            print
+  static const bool kIdents[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1,
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+  };
+  return kIdents[(int)c];
 }
 
 bool Tokenizer::ExpectToken(Token::Type expected, string* err) {