From dean-clamav@arctic.org Fri May 28 16:47:35 2004
Date: Fri, 28 May 2004 16:47:19 -0700 (PDT)
From: dean gaudet <dean-clamav@arctic.org>
To: bugs@clamav.net
Subject: two small cli_findpos tweaks lead to 40% speedup

two changes to cli_findpos produce a 40% speedup.  i measured using a
handful of windows executables and dlls on a 1GHz p-m... however i'd
expect similar benefits everywhere, especially from the
strength-reduction.

- most of the improvement:  strength-reduce the (bufferpos%length)
  operation -- the only remaining modulus was hoisted outside the loop,
  and inside the loop it's a much less expensive if (bufferpos==length)
  test.

- inline cli_findpos.  i'm not even sure cli_findpos needs to be extern?
  given that it's extern it ends up being called indirectly on linux for
  shared lib linkage.  but by moving it and indicating it inline much of
  the redundant computation is eliminated by the compiler.

-dean

patch against top of CVS.

Index: libclamav/matcher.c
===================================================================
RCS file: /cvsroot/clamav/clamav-devel/libclamav/matcher.c,v
retrieving revision 1.10
diff -p -u -r1.10 matcher.c
--- libclamav/matcher.c	5 Apr 2004 21:42:11 -0000	1.10
+++ libclamav/matcher.c	28 May 2004 23:06:03 -0000
@@ -193,6 +193,32 @@ void cl_freetrie(struct cl_node *root)
     free(root);
 }

+int inline cli_findpos(const char *buffer, int offset, int length, const struct cli_patt *pattern)
+{
+	int bufferpos = offset + CL_MIN_LENGTH;
+	int postfixend = offset + length;
+	unsigned int i;
+
+    if (bufferpos >= length)
+	bufferpos %= length;
+
+    for(i = CL_MIN_LENGTH; i < pattern->length; i++) {
+
+	if(bufferpos == postfixend)
+	    return 0;
+
+	if(pattern->pattern[i] != CLI_IGN && (char) pattern->pattern[i] != buffer[bufferpos])
+	    return 0;
+
+	bufferpos++;
+
+	if (bufferpos == length)
+	    bufferpos = 0;
+    }
+
+    return 1;
+}
+
 int cli_scanbuff(const char *buffer, unsigned int length, const char **virname, const struct cl_node *root, int *partcnt)
 {
 	struct cl_node *current;
@@ -257,26 +283,3 @@ int cl_scanbuff(const char *buffer, unsi
     free(partcnt);
     return ret;
 }
-
-int cli_findpos(const char *buffer, int offset, int length, const struct cli_patt *pattern)
-{
-	int bufferpos = offset + CL_MIN_LENGTH;
-	int postfixend = offset + length;
-	unsigned int i;
-
-
-    for(i = CL_MIN_LENGTH; i < pattern->length; i++) {
-
-	bufferpos %= length;
-
-	if(bufferpos == postfixend)
-	    return 0;
-
-	if(pattern->pattern[i] != CLI_IGN && (char) pattern->pattern[i] != buffer[bufferpos])
-	    return 0;
-
-	bufferpos++;
-    }
-
-    return 1;
-}
