diff options
author | Denys Vlasenko | 2016-09-29 19:50:55 +0200 |
---|---|---|
committer | Denys Vlasenko | 2016-09-29 19:50:55 +0200 |
commit | 46e6498b2afccd093d03697313e0d0c2f6e4d38d (patch) | |
tree | 7527d9c60c2e58da81242bdaa185ff894f26a496 /shell | |
parent | 657086a3dc573649165a5271473fa1bcf58dc9ed (diff) | |
download | busybox-46e6498b2afccd093d03697313e0d0c2f6e4d38d.zip busybox-46e6498b2afccd093d03697313e0d0c2f6e4d38d.tar.gz |
hush: speed optimizations
Make o_addchr() faster: do not call o_grow_by() each time.
Create i_getch_and_eat_bkslash_nl(), use it instead of peek+getch pair.
function old new delta
o_addchr 42 54 +12
parse_dollar 761 771 +10
o_grow_by 48 37 -11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 24/-11) Total: 11 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/shell/hush.c b/shell/hush.c index 177a794..65d7d87 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2373,7 +2373,7 @@ static ALWAYS_INLINE void o_free_unsafe(o_string *o) static void o_grow_by(o_string *o, int len) { if (o->length + len > o->maxlen) { - o->maxlen += (2*len > B_CHUNK ? 2*len : B_CHUNK); + o->maxlen += (2 * len) | (B_CHUNK-1); o->data = xrealloc(o->data, 1 + o->maxlen); } } @@ -2381,10 +2381,16 @@ static void o_grow_by(o_string *o, int len) static void o_addchr(o_string *o, int ch) { debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o); + if (o->length < o->maxlen) { + /* likely. avoid o_grow_by() call */ + add: + o->data[o->length] = ch; + o->length++; + o->data[o->length] = '\0'; + return; + } o_grow_by(o, 1); - o->data[o->length] = ch; - o->length++; - o->data[o->length] = '\0'; + goto add; } #if 0 @@ -3909,6 +3915,22 @@ static int parse_group(o_string *dest, struct parse_context *ctx, /* command remains "open", available for possible redirects */ } +static int i_getch_and_eat_bkslash_nl(struct in_str *input) +{ + for (;;) { + int ch, ch2; + + ch = i_getch(input); + if (ch != '\\') + return ch; + ch2 = i_peek(input); + if (ch2 != '\n') + return ch; + /* backslash+newline, skip it */ + i_getch(input); + } +} + static int i_peek_and_eat_bkslash_nl(struct in_str *input) { for (;;) { @@ -4149,8 +4171,7 @@ static int parse_dollar(o_string *as_string, ch = i_getch(input); /* eat '{' */ nommu_addchr(as_string, ch); - i_peek_and_eat_bkslash_nl(input); - ch = i_getch(input); /* first char after '{' */ + ch = i_getch_and_eat_bkslash_nl(input); /* first char after '{' */ /* It should be ${?}, or ${#var}, * or even ${?+subst} - operator acting on a special variable, * or the beginning of variable name. |