From ab9a98602f9a0c37f9382a57e421fe4e058d4a67 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 26 Dec 2018 20:30:47 +0100 Subject: bc: simple speedups function old new delta bc_parse_pushName 20 56 +36 bc_program_index 47 71 +24 bc_parse_pushIndex 52 58 +6 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 66/0) Total: 66 bytes Signed-off-by: Denys Vlasenko --- miscutils/bc.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'miscutils') diff --git a/miscutils/bc.c b/miscutils/bc.c index 2569967..cf04e9f 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -3439,17 +3439,38 @@ static void bc_parse_push(char i) static void bc_parse_pushName(char *name) { +#if 1 + BcVec *code = &G.prs.func->code; + size_t pos = code->len; + size_t len = strlen(name) + 1; + + bc_vec_expand(code, pos + len); + strcpy(code->v + pos, name); + code->len = pos + len; +#else + // Smaller code, but way slow: do { bc_parse_push(*name); } while (*name++); +#endif } +// Indexes < 0xfc are encoded verbatim, else first byte is +// 0xfc, 0xfd, 0xfe or 0xff, encoding "1..4 bytes", +// followed by that many bytes, lsb first. +// (The above describes 32-bit case). +#define SMALL_INDEX_LIMIT (0x100 - sizeof(size_t)) + static void bc_parse_pushIndex(size_t idx) { size_t mask; unsigned amt; dbg_lex("%s:%d pushing index %zd", __func__, __LINE__, idx); + if (idx < SMALL_INDEX_LIMIT) { + goto push_idx; + } + mask = ((size_t)0xff) << (sizeof(idx) * 8 - 8); amt = sizeof(idx); do { @@ -3458,9 +3479,10 @@ static void bc_parse_pushIndex(size_t idx) amt--; } while (amt != 0); - bc_parse_push(amt); + bc_parse_push(SMALL_INDEX_LIMIT + amt); while (idx != 0) { + push_idx: bc_parse_push((unsigned char)idx); idx >>= 8; } @@ -5257,6 +5279,11 @@ static size_t bc_program_index(char *code, size_t *bgn) size_t res; amt = *bytes++; + if (amt < SMALL_INDEX_LIMIT) { + *bgn += 1; + return amt; + } + amt -= SMALL_INDEX_LIMIT; *bgn += amt + 1; amt *= 8; -- cgit v1.1