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); }