I've been looking at ways to make user defined functions run with less
overhead, and found that OP_STRING and OP_STRING8 arguments are having
strlen() called on them every time the function is invoked.  Attached
is a tiny patch that causes expr.c to pass the length of the argument
as P1 and also causes vdbe.c to use this argument if it exists.

Although the gain here is probably small for typical users, in the
case I'm optimizing for (a tight loop around a user defined function
with multiple long string args) I got about a 5% overall improvement.

I've used this patch a little bit, but haven't tested it well.  It
doesn't seem to cause any problems with the test suite.  A similar
optimization could also probably be done for OP_REAL, but since I
wasn't testing that I didn't put it in.

--nate

(In the future, should I post proposed patches here for discussion, or
should I just add them to the bug tracker as enhancements?)




--- src/expr.c~ 2005-09-23 15:11:54.000000000 -0600
+++ src/expr.c  2005-11-15 15:43:08.000000000 -0700
@@ -1482,7 +1482,9 @@
       assert( TK_FLOAT==OP_Real );
       assert( TK_STRING==OP_String8 );
       sqlite3DequoteExpr(pExpr);
-      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n);
+      /* calculate strlen() since token.n is off if Dequote occurred */
+      sqlite3VdbeOp3(v, op, pExpr->token.z ? strlen(pExpr->token.z) : 0, 
+                    0, pExpr->token.z, pExpr->token.n);
       break;
     }
     case TK_NULL: {
--- src/vdbe.c~ 2005-09-20 11:42:23.000000000 -0600
+++ src/vdbe.c  2005-11-15 14:00:23.000000000 -0700
@@ -689,7 +689,7 @@
   pTos->z = pOp->p3;
 #ifndef SQLITE_OMIT_UTF16
   if( db->enc==SQLITE_UTF8 ){
-    pTos->n = strlen(pTos->z);
+    pTos->n = pOp->p1 > 0 ? pOp->p1 : strlen(pTos->z); /* use given strlen */
   }else{
     pTos->n  = sqlite3utf16ByteLen(pTos->z, -1);
   }

Reply via email to