From 741297616d8e8293ff5790fcf258b35a829fada1 Mon Sep 17 00:00:00 2001 From: bbgan <2893129936@qq.com> Date: Thu, 16 May 2024 16:18:55 +0800 Subject: [PATCH] improve decode_varint[struct_pb] --- iguana/pb_util.hpp | 118 ++++++++++++++++++++++-------------------- iguana/reflection.hpp | 2 +- 2 files changed, 63 insertions(+), 57 deletions(-) diff --git a/iguana/pb_util.hpp b/iguana/pb_util.hpp index 0dc5faac..44c26af5 100644 --- a/iguana/pb_util.hpp +++ b/iguana/pb_util.hpp @@ -106,63 +106,69 @@ IGUANA_INLINE uint64_t decode_varint(T& data, size_t& pos) { const int8_t* p = begin; uint64_t val = 0; - // end is always greater than or equal to begin, so this subtraction is safe - if (size_t(end - begin) >= 10) { // fast path - int64_t b; - do { - b = *p++; - val = (b & 0x7f); - if (b >= 0) { - break; - } - b = *p++; - val |= (b & 0x7f) << 7; - if (b >= 0) { - break; - } - b = *p++; - val |= (b & 0x7f) << 14; - if (b >= 0) { - break; - } - b = *p++; - val |= (b & 0x7f) << 21; - if (b >= 0) { - break; - } - b = *p++; - val |= (b & 0x7f) << 28; - if (b >= 0) { - break; - } - b = *p++; - val |= (b & 0x7f) << 35; - if (b >= 0) { - break; - } - b = *p++; - val |= (b & 0x7f) << 42; - if (b >= 0) { - break; - } - b = *p++; - val |= (b & 0x7f) << 49; - if (b >= 0) { - break; - } - b = *p++; - val |= (b & 0x7f) << 56; - if (b >= 0) { - break; - } - b = *p++; - val |= (b & 0x01) << 63; - if (b >= 0) { - break; - } - throw std::invalid_argument("Invalid varint value: too many bytes."); - } while (false); + if ((static_cast(*p) & 0x80) == 0) { + pos = 1; + return static_cast(*p); } + + // end is always greater than or equal to begin, so this subtraction is safe + if (size_t(end - begin) >= 10) + IGUANA_LIKELY { // fast path + int64_t b; + do { + b = *p++; + val = (b & 0x7f); + if (b >= 0) { + break; + } + b = *p++; + val |= (b & 0x7f) << 7; + if (b >= 0) { + break; + } + b = *p++; + val |= (b & 0x7f) << 14; + if (b >= 0) { + break; + } + b = *p++; + val |= (b & 0x7f) << 21; + if (b >= 0) { + break; + } + b = *p++; + val |= (b & 0x7f) << 28; + if (b >= 0) { + break; + } + b = *p++; + val |= (b & 0x7f) << 35; + if (b >= 0) { + break; + } + b = *p++; + val |= (b & 0x7f) << 42; + if (b >= 0) { + break; + } + b = *p++; + val |= (b & 0x7f) << 49; + if (b >= 0) { + break; + } + b = *p++; + val |= (b & 0x7f) << 56; + if (b >= 0) { + break; + } + b = *p++; + val |= (b & 0x01) << 63; + if (b >= 0) { + break; + } + throw std::invalid_argument("Invalid varint value: too many bytes."); + } while (false); + } else { int shift = 0; while (p != end && *p < 0) { diff --git a/iguana/reflection.hpp b/iguana/reflection.hpp index 7cd28a18..c2ff73bd 100644 --- a/iguana/reflection.hpp +++ b/iguana/reflection.hpp @@ -700,7 +700,7 @@ struct field_t { using value_type = typename member_traits::value_type; using sub_type = ElementType; constexpr field_t() = default; - constexpr field_t(T member, uint32_t number, frozen::string name) + constexpr field_t(T member, uint32_t number, frozen::string name = "") : member_ptr(member), field_name(name), field_no(number) {} T member_ptr;