Significant speed improvement for 1.2.3

Florian Weimer fw at deneb.enyo.de
Sat Oct 18 19:19:25 CEST 2003


I've just discovered kcachegrind (very nice tool!), and it motivated me
to write the patch appended below.

The old skip_buf() code in g10/parse-packet.c is very inefficient, it
discarded the characters one-by-one.  The new version, moved to
utils/iobuf.c, usually needs one iteration of the loop and is much, much
faster.  As a result, the simulated clock time for the skipping
operation drops from 40% to 3%.  Measurements using real execution time
confirm that it's a significant win (with my keyring, signature
verification time goes down from about 700 ms to 500 ms).

BTW, is there are a public GNU arch archive for GnuPG?

--- orig/g10/parse-packet.c
+++ mod/g10/parse-packet.c
@@ -49,7 +49,6 @@
 static int  copy_packet( IOBUF inp, IOBUF out, int pkttype,
 					       unsigned long pktlen );
 static void skip_packet( IOBUF inp, int pkttype, unsigned long pktlen );
-static void skip_rest( IOBUF inp, unsigned long pktlen );
 static void *read_rest( IOBUF inp, size_t pktlen );
 static int  parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen,
 							     PACKET *packet );
@@ -422,7 +421,7 @@
                         && pkttype != PKT_PUBLIC_KEY
                         && pkttype != PKT_SECRET_SUBKEY
                         && pkttype != PKT_SECRET_KEY  ) ) {
-	skip_rest(inp, pktlen);
+	iobuf_skip_rest(inp, pktlen);
 	*skip = 1;
 	rc = 0;
 	goto leave;
@@ -580,24 +579,9 @@
 	    return;
 	}
     }
-    skip_rest(inp,pktlen);
+    iobuf_skip_rest(inp,pktlen);
 }
 
-static void
-skip_rest( IOBUF inp, unsigned long pktlen )
-{
-    if( iobuf_in_block_mode(inp) ) {
-	while( iobuf_get(inp) != -1 )
-		;
-    }
-    else {
-	for( ; pktlen; pktlen-- )
-	    if( iobuf_get(inp) == -1 )
-		break;
-    }
-}
-
-
 static void *
 read_rest( IOBUF inp, size_t pktlen )
 {
@@ -696,7 +680,7 @@
     }
 
   leave:
-    skip_rest(inp, pktlen);
+    iobuf_skip_rest(inp, pktlen);
     return rc;
 }
 
@@ -750,7 +734,7 @@
     }
 
   leave:
-    skip_rest(inp, pktlen);
+    iobuf_skip_rest(inp, pktlen);
     return rc;
 }
 
@@ -1360,7 +1344,7 @@
     }
 
   leave:
-    skip_rest(inp, pktlen);
+    iobuf_skip_rest(inp, pktlen);
     return rc;
 }
 
@@ -1398,7 +1382,7 @@
 
 
   leave:
-    skip_rest(inp, pktlen);
+    iobuf_skip_rest(inp, pktlen);
     return rc;
 }
 
@@ -1477,7 +1461,7 @@
 	    }
 	    printf("\"\n");
 	}
-	skip_rest(inp, pktlen);
+	iobuf_skip_rest(inp, pktlen);
 	return 0;
     }
     else if( version == 4 )
@@ -1809,7 +1793,7 @@
     }
 
   leave:
-    skip_rest(inp, pktlen);
+    iobuf_skip_rest(inp, pktlen);
     return rc;
 }
 
@@ -2043,7 +2027,7 @@
       if( list_mode )
 	printf(":trust packet: empty\n");
     }
-  skip_rest (inp, pktlen);
+  iobuf_skip_rest (inp, pktlen);
 }
 
 
@@ -2168,7 +2152,7 @@
     if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
 	log_error("packet(%d) too short\n", pkttype);
         rc = G10ERR_INVALID_PACKET;
-	skip_rest(inp, pktlen);
+	iobuf_skip_rest(inp, pktlen);
 	goto leave;
     }
     if( list_mode ) {
@@ -2272,7 +2256,7 @@
         }
         putchar('\n');
     }
-    skip_rest(inp,pktlen);
+    iobuf_skip_rest(inp,pktlen);
     return G10ERR_INVALID_PACKET;
 }
 


--- orig/include/iobuf.h
+++ mod/include/iobuf.h
@@ -135,6 +135,8 @@
 
 int iobuf_translate_file_handle ( int fd, int for_write );
 
+void iobuf_skip_rest( IOBUF a, unsigned long n);
+
 
 /* get a byte form the iobuf; must check for eof prior to this function
  * this function returns values in the range 0 .. 255 or -1 to indicate EOF


--- orig/util/iobuf.c
+++ mod/util/iobuf.c
@@ -2190,3 +2190,39 @@
 #endif
     return fd;
 }
+
+void
+iobuf_skip_rest(IOBUF a, unsigned long n)
+{
+    if ( iobuf_in_block_mode(a) ) {
+	for (;;) {
+	    if (a->nofast || a->d.start >= a->d.len) {
+		if (iobuf_readbyte (a) == -1) {
+		    break;
+		}
+	    } else {
+		unsigned long count = a->d.len - a->d.start;
+		a->nbytes += count;
+		a->d.start = a->d.len;
+	    }
+	}
+    } else {
+	unsigned long remaining = n;
+	while (remaining > 0) {
+	    if (a->nofast || a->d.start >= a->d.len) {
+		if (iobuf_readbyte (a) == -1) {
+		    break;
+		}
+		--remaining;
+	    } else {
+		unsigned long count = a->d.len - a->d.start;
+		if (count > remaining) {
+		    count = remaining;
+		}
+		a->nbytes += count;
+		a->d.start += count;
+		remaining -= count;
+	    }
+	}
+    }
+}






More information about the Gnupg-devel mailing list