]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Performance optimizations on the JSON parser.
authordrh <drh@noemail.net>
Thu, 24 Sep 2015 01:06:37 +0000 (01:06 +0000)
committerdrh <drh@noemail.net>
Thu, 24 Sep 2015 01:06:37 +0000 (01:06 +0000)
FossilOrigin-Name: 7dd4b07a42eb84589d34430b9d7bfa88fbd743eb

ext/misc/json1.c
manifest
manifest.uuid

index 3dd831f9c572989c5adda6de54671a9066be6870..cf766120cdb958e5bea1a1a3180c32ffd11a5eac 100644 (file)
@@ -37,10 +37,34 @@ SQLITE_EXTENSION_INIT1
 ** Versions of isspace(), isalnum() and isdigit() to which it is safe
 ** to pass signed char values.
 */
-#define safe_isspace(x) isspace((unsigned char)(x))
 #define safe_isdigit(x) isdigit((unsigned char)(x))
 #define safe_isalnum(x) isalnum((unsigned char)(x))
 
+/*
+** Growing our own isspace() routine this way is twice as fast as
+** the library isspace() function, resulting in a 7% overall performance
+** increase for the parser.  (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
+*/
+static const char jsonIsSpace[] = {
+  0, 0, 0, 0, 0, 0, 0, 0,     0, 1, 1, 0, 1, 1, 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, 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, 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, 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, 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, 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, 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, 0,
+};
+#define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
+
 /* Unsigned integer types */
 typedef sqlite3_uint64 u64;
 typedef unsigned int u32;
@@ -548,6 +572,44 @@ static void jsonReturn(
   }
 }
 
+/* Forward reference */
+static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
+
+/*
+** A macro to hint to the compiler that a function should not be
+** inlined.
+*/
+#if defined(__GNUC__)
+#  define JSON_NOINLINE  __attribute__((noinline))
+#elif defined(_MSC_VER) && _MSC_VER>=1310
+#  define JSON_NOINLINE  __declspec(noinline)
+#else
+#  define JSON_NOINLINE
+#endif
+
+
+static JSON_NOINLINE int jsonParseAddNodeExpand(
+  JsonParse *pParse,        /* Append the node to this object */
+  u32 eType,                /* Node type */
+  u32 n,                    /* Content size or sub-node count */
+  const char *zContent      /* Content */
+){
+  u32 nNew;
+  JsonNode *pNew;
+  assert( pParse->nNode>=pParse->nAlloc );
+  if( pParse->oom ) return -1;
+  nNew = pParse->nAlloc*2 + 10;
+  pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
+  if( pNew==0 ){
+    pParse->oom = 1;
+    return -1;
+  }
+  pParse->nAlloc = nNew;
+  pParse->aNode = pNew;
+  assert( pParse->nNode<pParse->nAlloc );
+  return jsonParseAddNode(pParse, eType, n, zContent);
+}
+
 /*
 ** Create a new JsonNode instance based on the arguments and append that
 ** instance to the JsonParse.  Return the index in pParse->aNode[] of the
@@ -561,17 +623,7 @@ static int jsonParseAddNode(
 ){
   JsonNode *p;
   if( pParse->nNode>=pParse->nAlloc ){
-    u32 nNew;
-    JsonNode *pNew;
-    if( pParse->oom ) return -1;
-    nNew = pParse->nAlloc*2 + 10;
-    pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew);
-    if( pNew==0 ){
-      pParse->oom = 1;
-      return -1;
-    }
-    pParse->nAlloc = nNew;
-    pParse->aNode = pNew;
+    return jsonParseAddNodeExpand(pParse, eType, n, zContent);
   }
   p = &pParse->aNode[pParse->nNode];
   p->eType = (u8)eType;
@@ -1783,7 +1835,7 @@ static int jsonEachFilter(
     jsonEachCursorReset(p);
     return SQLITE_NOMEM;
   }else{
-    JsonNode *pNode;
+    JsonNode *pNode = 0;
     if( idxNum==3 ){
       const char *zErr = 0;
       zRoot = (const char*)sqlite3_value_text(argv[1]);
index bf24e71000f27974bd81165a08c90fe67dc5d864..28c26272cb75b1b004525aa35549d174ce7fa1db 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Take\scare\sthat\sthe\snumber\sof\sreserved\sbits\sper\spage\sis\sconsistent\sbetween\s\nthe\ssource\sand\sdestination\sdatabases\swhen\sdoing\sthe\sback-copy\son\sa\sVACUUM.
-D 2015-09-23T19:17:23.388
+C Performance\soptimizations\son\sthe\sJSON\sparser.
+D 2015-09-24T01:06:37.957
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in e1afa6fb2de2bddd50e0ddae8166c2ee9d69b301
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -195,7 +195,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
 F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767
 F ext/misc/ieee754.c b0362167289170627659e84173f5d2e8fee8566e
-F ext/misc/json1.c 7659013d8d84a263ae60cd01cdc25d3596cf5063
+F ext/misc/json1.c 7d0000e380785587d463087aa9b35969727bd441
 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
@@ -1388,7 +1388,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 10a214fdb3c13b25e0bdd15c975c21c8890c47ee
-R 2b1245a60b251810f1e390834307b519
+P 5b61b72f5424a2d9bb4e68eb95026cd63f003db9
+R 573d7fd2b2ba49c88643e63838f29bfa
 U drh
-Z 954cd22d559279a8020d621e1b476fcf
+Z e6052053910d25a8548d981b3aa4b989
index 5731652f022b623b8c2113cace1eab025c107c43..799899d2bdcfe2889237e334c972f7aa7069dfe0 100644 (file)
@@ -1 +1 @@
-5b61b72f5424a2d9bb4e68eb95026cd63f003db9
\ No newline at end of file
+7dd4b07a42eb84589d34430b9d7bfa88fbd743eb
\ No newline at end of file