From eff9e11150c0bfb6baf5d6bec2351034b72d95ed Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Thu, 14 Nov 2013 17:56:42 +0200 Subject: Optimize the common case of 1-byte reads for varints. For PB_BUFFER_ONLY configuration, this gives 20% speedup without increasing code size. --- pb_decode.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/pb_decode.c b/pb_decode.c index 90fa18d2..a887d155 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -124,6 +124,26 @@ bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count) 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 stream; @@ -149,7 +169,7 @@ static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) uint8_t byte; uint32_t result; - if (!pb_read(stream, &byte, 1)) + if (!pb_readbyte(stream, &byte)) return false; if (!(byte & 0x80)) @@ -168,7 +188,7 @@ static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) if (bitpos >= 32) PB_RETURN_ERROR(stream, "varint overflow"); - if (!pb_read(stream, &byte, 1)) + if (!pb_readbyte(stream, &byte)) return false; 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) PB_RETURN_ERROR(stream, "varint overflow"); - if (!pb_read(stream, &byte, 1)) + if (!pb_readbyte(stream, &byte)) return false; result |= (uint64_t)(byte & 0x7F) << bitpos; -- cgit 1.2.3-korg