diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-07-27 17:53:55 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-07-27 17:53:55 +0200 |
commit | 49cc3cac30c504abdbd2c075928f5711da4066e8 (patch) | |
tree | 83760d4340bd8a39225f76650d34372137de9ed7 | |
parent | c450437a4e631378cd6a2dc06a5923ce811a950d (diff) | |
download | busybox-w32-49cc3cac30c504abdbd2c075928f5711da4066e8.tar.gz busybox-w32-49cc3cac30c504abdbd2c075928f5711da4066e8.tar.bz2 busybox-w32-49cc3cac30c504abdbd2c075928f5711da4066e8.zip |
hush: optimize ${var/pattern/repl} for trivial patterns
function old new delta
expand_one_var 2353 2507 +154
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 13 | ||||
-rw-r--r-- | shell/match.c | 3 |
2 files changed, 14 insertions, 2 deletions
diff --git a/shell/hush.c b/shell/hush.c index 6b910569f..179155f66 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -6466,6 +6466,19 @@ static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p) | |||
6466 | /* ${var/[/]pattern[/repl]} helpers */ | 6466 | /* ${var/[/]pattern[/repl]} helpers */ |
6467 | static char *strstr_pattern(char *val, const char *pattern, int *size) | 6467 | static char *strstr_pattern(char *val, const char *pattern, int *size) |
6468 | { | 6468 | { |
6469 | if (!strpbrk(pattern, "*?[\\")) { | ||
6470 | /* Optimization for trivial patterns. | ||
6471 | * Testcase for very slow replace (performs about 22k replaces): | ||
6472 | * x=:::::::::::::::::::::: | ||
6473 | * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} | ||
6474 | * echo "${x//:/|}" | ||
6475 | */ | ||
6476 | char *found = strstr(val, pattern); | ||
6477 | if (found) | ||
6478 | *size = strlen(pattern); | ||
6479 | return found; | ||
6480 | } | ||
6481 | |||
6469 | while (1) { | 6482 | while (1) { |
6470 | char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF); | 6483 | char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF); |
6471 | debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end); | 6484 | debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end); |
diff --git a/shell/match.c b/shell/match.c index ee8abb2db..90f77546d 100644 --- a/shell/match.c +++ b/shell/match.c | |||
@@ -64,11 +64,10 @@ char* FAST_FUNC scan_and_match(char *string, const char *pattern, unsigned flags | |||
64 | } | 64 | } |
65 | 65 | ||
66 | while (loc != end) { | 66 | while (loc != end) { |
67 | char c; | ||
68 | int r; | 67 | int r; |
69 | 68 | ||
70 | c = *loc; | ||
71 | if (flags & SCAN_MATCH_LEFT_HALF) { | 69 | if (flags & SCAN_MATCH_LEFT_HALF) { |
70 | char c = *loc; | ||
72 | *loc = '\0'; | 71 | *loc = '\0'; |
73 | r = fnmatch(pattern, string, 0); | 72 | r = fnmatch(pattern, string, 0); |
74 | //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r); | 73 | //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r); |