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;
|
||||
while ((c = iobuf_get (a)) != -1)
|
||||
while (1)
|
||||
{
|
||||
*p++ = c;
|
||||
nbytes++;
|
||||
if (c == '\n')
|
||||
break;
|
||||
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;
|
||||
nbytes++;
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
if (nbytes == length - 1)
|
||||
/* We don't have enough space to add a \n and a \0. Increase
|
||||
|
Loading…
x
Reference in New Issue
Block a user