aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2020-08-01 11:31:22 +0100
committerRon Yorston <rmy@pobox.com>2020-08-01 11:31:22 +0100
commit32862e44e0dd011f505e35ca30aad015e842cbdd (patch)
treeb4d276dfc872658f8ee38495cac07161114de53e
parentcfa888eb571d92d4de02b406f0dad15e4fa26d19 (diff)
downloadbusybox-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.c35
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