Optimize the common case of 1-byte reads for varints.

For PB_BUFFER_ONLY configuration, this gives 20% speedup without
increasing code size.
This commit is contained in:
Petteri Aimonen
2013-11-14 17:56:42 +02:00
parent 5813144246
commit eff9e11150

View File

@@ -124,6 +124,26 @@ bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count)
return true; return true;
} }
/* Read a single byte from input stream. buf may not be NULL.
* This is an optimization for the varint decoding. */
static bool checkreturn pb_readbyte(pb_istream_t *stream, uint8_t *buf)
{
if (!stream->bytes_left)
PB_RETURN_ERROR(stream, "end-of-stream");
#ifndef PB_BUFFER_ONLY
if (!stream->callback(stream, buf, 1))
PB_RETURN_ERROR(stream, "io error");
#else
*buf = *(uint8_t*)stream->state;
stream->state = (uint8_t*)stream->state + 1;
#endif
stream->bytes_left--;
return true;
}
pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize) pb_istream_t pb_istream_from_buffer(uint8_t *buf, size_t bufsize)
{ {
pb_istream_t stream; pb_istream_t stream;
@@ -149,7 +169,7 @@ static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
uint8_t byte; uint8_t byte;
uint32_t result; uint32_t result;
if (!pb_read(stream, &byte, 1)) if (!pb_readbyte(stream, &byte))
return false; return false;
if (!(byte & 0x80)) if (!(byte & 0x80))
@@ -168,7 +188,7 @@ static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest)
if (bitpos >= 32) if (bitpos >= 32)
PB_RETURN_ERROR(stream, "varint overflow"); PB_RETURN_ERROR(stream, "varint overflow");
if (!pb_read(stream, &byte, 1)) if (!pb_readbyte(stream, &byte))
return false; return false;
result |= (uint32_t)(byte & 0x7F) << bitpos; result |= (uint32_t)(byte & 0x7F) << bitpos;
@@ -191,7 +211,7 @@ bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest)
if (bitpos >= 64) if (bitpos >= 64)
PB_RETURN_ERROR(stream, "varint overflow"); PB_RETURN_ERROR(stream, "varint overflow");
if (!pb_read(stream, &byte, 1)) if (!pb_readbyte(stream, &byte))
return false; return false;
result |= (uint64_t)(byte & 0x7F) << bitpos; result |= (uint64_t)(byte & 0x7F) << bitpos;