diff options
author | Ron Yorston <rmy@pobox.com> | 2020-08-01 11:31:22 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-08-01 11:31:22 +0100 |
commit | 32862e44e0dd011f505e35ca30aad015e842cbdd (patch) | |
tree | b4d276dfc872658f8ee38495cac07161114de53e | |
parent | cfa888eb571d92d4de02b406f0dad15e4fa26d19 (diff) | |
download | busybox-w32-awk_faster.tar.gz busybox-w32-awk_faster.tar.bz2 busybox-w32-awk_faster.zip |
awk: speed improvementsawk_faster
Improve performance in certain cases at the cost of an additional
144 bytes in the binary.
- Reinstate (and fix) the original code to speed up assignment of a
temporary string to a variable.
- Replace use of xasprintf() for string concatentation with explicit
string manipulation. This could be faster still if Windows had an
optimised stpcpy().
The enhancement is not enabled by default.
This test case:
BEGIN{while(++i<30000) s=s i}
is 18 times faster. The less extreme:
BEGIN{while(++i<1000000) s="abc " i}
is 30% faster.
See GitHub issue #193.
-rw-r--r-- | editors/awk.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/editors/awk.c b/editors/awk.c index 509f4ddd8..57d354858 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -30,6 +30,14 @@ | |||
30 | //config: * simultaneous use of -f and -e on the command line. | 30 | //config: * simultaneous use of -f and -e on the command line. |
31 | //config: This enables the use of awk library files. | 31 | //config: This enables the use of awk library files. |
32 | //config: Example: awk -f mylib.awk -e '{print myfunction($1);}' ... | 32 | //config: Example: awk -f mylib.awk -e '{print myfunction($1);}' ... |
33 | //config:config FEATURE_AWK_FASTER | ||
34 | //config: bool "Enable some speed enhancements" | ||
35 | //config: default n | ||
36 | //config: depends on AWK | ||
37 | //config: help | ||
38 | //config: Enable enhancements that speed up string concatenation and | ||
39 | //config: assignment of temporary strings to a variable. Increases | ||
40 | //config: size of binary by 144 bytes. | ||
33 | 41 | ||
34 | //applet:IF_AWK(APPLET_NOEXEC(awk, awk, BB_DIR_USR_BIN, BB_SUID_DROP, awk)) | 42 | //applet:IF_AWK(APPLET_NOEXEC(awk, awk, BB_DIR_USR_BIN, BB_SUID_DROP, awk)) |
35 | 43 | ||
@@ -2766,15 +2774,14 @@ static var *evaluate(node *op, var *res) | |||
2766 | 2774 | ||
2767 | case XC( OC_MOVE ): | 2775 | case XC( OC_MOVE ): |
2768 | debug_printf_eval("MOVE\n"); | 2776 | debug_printf_eval("MOVE\n"); |
2769 | /* if source is a temporary string, jusk relink it to dest */ | 2777 | #if ENABLE_FEATURE_AWK_FASTER |
2770 | //Disabled: if R.v is numeric but happens to have cached R.v->string, | 2778 | /* if source is a temporary string, just relink it to dest */ |
2771 | //then L.v ends up being a string, which is wrong | 2779 | if (R.v == v1+1 && R.v->string && !(R.v->type & VF_NUMBER)) { |
2772 | // if (R.v == v1+1 && R.v->string) { | 2780 | res = setvar_p(L.v, R.v->string); |
2773 | // res = setvar_p(L.v, R.v->string); | 2781 | R.v->string = NULL; |
2774 | // R.v->string = NULL; | 2782 | } else |
2775 | // } else { | 2783 | #endif |
2776 | res = copyvar(L.v, R.v); | 2784 | res = copyvar(L.v, R.v); |
2777 | // } | ||
2778 | break; | 2785 | break; |
2779 | 2786 | ||
2780 | case XC( OC_TERNARY ): | 2787 | case XC( OC_TERNARY ): |
@@ -3025,9 +3032,21 @@ static var *evaluate(node *op, var *res) | |||
3025 | case XC( OC_CONCAT ): | 3032 | case XC( OC_CONCAT ): |
3026 | case XC( OC_COMMA ): { | 3033 | case XC( OC_COMMA ): { |
3027 | const char *sep = ""; | 3034 | const char *sep = ""; |
3035 | #if ENABLE_FEATURE_AWK_FASTER | ||
3036 | char *buf; | ||
3037 | #endif | ||
3028 | if ((opinfo & OPCLSMASK) == OC_COMMA) | 3038 | if ((opinfo & OPCLSMASK) == OC_COMMA) |
3029 | sep = getvar_s(intvar[SUBSEP]); | 3039 | sep = getvar_s(intvar[SUBSEP]); |
3040 | #if ENABLE_FEATURE_AWK_FASTER | ||
3041 | buf = xmalloc(strlen(L.s) + strlen(sep) + strlen(R.s) + 1); | ||
3042 | strcpy(buf, L.s); | ||
3043 | if (*sep != '\0') | ||
3044 | strcat(buf, sep); | ||
3045 | strcat(buf, R.s); | ||
3046 | setvar_p(res, buf); | ||
3047 | #else | ||
3030 | setvar_p(res, xasprintf("%s%s%s", L.s, sep, R.s)); | 3048 | setvar_p(res, xasprintf("%s%s%s", L.s, sep, R.s)); |
3049 | #endif | ||
3031 | break; | 3050 | break; |
3032 | } | 3051 | } |
3033 | 3052 | ||