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