From 49b6040048a48e5936beaa44271fd9227ec8a753 Mon Sep 17 00:00:00 2001 From: Vadim Yanitskiy Date: Wed, 17 Nov 2021 06:21:28 +0300 Subject: [PATCH] bitvec_read_field(): optimize by expanding bytenum_from_bitnum() The bitvec_read_field() is used in performance critical places, such as the CSN.1 decoder in osmo-pcu. Thus the less conditional statements we have in the parsing loop, the better. The bitvec_get_bit_pos() alone is quite a complex function, which does check the boundaries and even supports the L/H syntax. Even if it gets inlined by the compiler, we don't really want to run redundant checks and run bitval2mask() on each iteration. Change-Id: I438fc82d33ab2edbabd4215ec7bc46afb07d50ab --- src/bitvec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bitvec.c b/src/bitvec.c index 2303a0df3..13deeff5b 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -491,8 +491,10 @@ uint64_t bitvec_read_field(struct bitvec *bv, unsigned int *read_index, unsigned errno = 0; for (i = 0; i < len; i++) { - int bit = bitvec_get_bit_pos((const struct bitvec *)bv, bv->cur_bit); - if (bit) + unsigned int bytenum = bytenum_from_bitnum(bv->cur_bit); + unsigned int bitnum = 7 - (bv->cur_bit % 8); + + if (bv->data[bytenum] & (1 << bitnum)) ui |= ((uint64_t)1 << (len - i - 1)); bv->cur_bit++; }