mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
common/iobuf: optimize iobuf_read_line
* common/iobuf.c (iobuf_read_line): Add fast path for finding '\n' character in buffer. -- This patch reduce per byte overhead in iobuf_read_line by avoiding using iobuf_get when possible and use memchr to find '\n'. This speeds armored decryption. Benchmark results below, tested on Intel Core i7-4790K (turbo off). Encrypted 2 GiB through pipe to ramfs file using AES128. Decrypt ramfs file out through pipe to /dev/null. before patch-set ---------------- gpg process armor: user time pipe transfer rate encrypt-aead: 13.8 140 MB/s decrypt-aead: 30.6 68 MB/s encrypt-cfb: 17.4 114 MB/s decrypt-cfb: 32.6 64 MB/s after (decrypt+iobuf opt) ------------------------- gpg process armor: user time pipe transfer rate decrypt-aead: 22.5 92 MB/s decrypt-cfb: 24.4 85 MB/s Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
This commit is contained in:
parent
47424881b2
commit
2b5718c1f7
@ -2610,12 +2610,50 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
p = buffer;
|
p = buffer;
|
||||||
while ((c = iobuf_get (a)) != -1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
if (!a->nofast && a->d.start < a->d.len && nbytes < length - 1)
|
||||||
|
/* Fast path for finding '\n' by using standard C library's optimized
|
||||||
|
memchr. */
|
||||||
|
{
|
||||||
|
unsigned size = a->d.len - a->d.start;
|
||||||
|
byte *newline_pos;
|
||||||
|
|
||||||
|
if (size > length - 1 - nbytes)
|
||||||
|
size = length - 1 - nbytes;
|
||||||
|
|
||||||
|
newline_pos = memchr (a->d.buf + a->d.start, '\n', size);
|
||||||
|
if (newline_pos)
|
||||||
|
{
|
||||||
|
/* Found newline, copy buffer and return. */
|
||||||
|
size = (newline_pos - (a->d.buf + a->d.start)) + 1;
|
||||||
|
memcpy (p, a->d.buf + a->d.start, size);
|
||||||
|
p += size;
|
||||||
|
nbytes += size;
|
||||||
|
a->d.start += size;
|
||||||
|
a->nbytes += size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No newline, copy buffer and continue. */
|
||||||
|
memcpy (p, a->d.buf + a->d.start, size);
|
||||||
|
p += size;
|
||||||
|
nbytes += size;
|
||||||
|
a->d.start += size;
|
||||||
|
a->nbytes += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c = iobuf_readbyte (a);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
*p++ = c;
|
*p++ = c;
|
||||||
nbytes++;
|
nbytes++;
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (nbytes == length - 1)
|
if (nbytes == length - 1)
|
||||||
/* We don't have enough space to add a \n and a \0. Increase
|
/* We don't have enough space to add a \n and a \0. Increase
|
||||||
|
Loading…
x
Reference in New Issue
Block a user