aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-06-29 19:07:36 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-06-29 19:07:36 +0200
commit3aff3b9cb81c1f574aaafaf3981e755c6639e2bc (patch)
tree1f67a3cc384ab9e7e4c9e030a469e6b0b9bb15dc
parentb3c91a127f8baecee0265ba92898ae1e718bdb31 (diff)
downloadbusybox-w32-3aff3b9cb81c1f574aaafaf3981e755c6639e2bc.tar.gz
busybox-w32-3aff3b9cb81c1f574aaafaf3981e755c6639e2bc.tar.bz2
busybox-w32-3aff3b9cb81c1f574aaafaf3981e755c6639e2bc.zip
awk: assorted optimizations
hash_find(): do not caclculate hash twice. Do not divide - can use cheap multiply-by-8 shift. nextword(): do not repeatedly increment in-memory value, do it in register, then store final result. hashwalk_init(): do not strlen() twice. function old new delta hash_search3 - 49 +49 hash_find 259 281 +22 nextword 19 16 -3 evaluate 3141 3137 -4 hash_search 54 28 -26 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/3 up/down: 71/-33) Total: 38 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/awk.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/editors/awk.c b/editors/awk.c
index 4e29b28cf..a4cd3cf93 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -696,6 +696,7 @@ static void hash_clear(xhash *hash)
696 while (hi) { 696 while (hi) {
697 thi = hi; 697 thi = hi;
698 hi = hi->next; 698 hi = hi->next;
699//FIXME: this assumes that it's a hash of *variables*:
699 free(thi->data.v.string); 700 free(thi->data.v.string);
700 free(thi); 701 free(thi);
701 } 702 }
@@ -714,11 +715,11 @@ static void hash_free(xhash *hash)
714#endif 715#endif
715 716
716/* find item in hash, return ptr to data, NULL if not found */ 717/* find item in hash, return ptr to data, NULL if not found */
717static void *hash_search(xhash *hash, const char *name) 718static NOINLINE void *hash_search3(xhash *hash, const char *name, unsigned idx)
718{ 719{
719 hash_item *hi; 720 hash_item *hi;
720 721
721 hi = hash->items[hashidx(name) % hash->csize]; 722 hi = hash->items[idx % hash->csize];
722 while (hi) { 723 while (hi) {
723 if (strcmp(hi->name, name) == 0) 724 if (strcmp(hi->name, name) == 0)
724 return &hi->data; 725 return &hi->data;
@@ -727,6 +728,11 @@ static void *hash_search(xhash *hash, const char *name)
727 return NULL; 728 return NULL;
728} 729}
729 730
731static void *hash_search(xhash *hash, const char *name)
732{
733 return hash_search3(hash, name, hashidx(name));
734}
735
730/* grow hash if it becomes too big */ 736/* grow hash if it becomes too big */
731static void hash_rebuild(xhash *hash) 737static void hash_rebuild(xhash *hash)
732{ 738{
@@ -762,16 +768,17 @@ static void *hash_find(xhash *hash, const char *name)
762 unsigned idx; 768 unsigned idx;
763 int l; 769 int l;
764 770
765 hi = hash_search(hash, name); 771 idx = hashidx(name);
772 hi = hash_search3(hash, name, idx);
766 if (!hi) { 773 if (!hi) {
767 if (++hash->nel / hash->csize > 10) 774 if (++hash->nel > hash->csize * 8)
768 hash_rebuild(hash); 775 hash_rebuild(hash);
769 776
770 l = strlen(name) + 1; 777 l = strlen(name) + 1;
771 hi = xzalloc(sizeof(*hi) + l); 778 hi = xzalloc(sizeof(*hi) + l);
772 strcpy(hi->name, name); 779 strcpy(hi->name, name);
773 780
774 idx = hashidx(name) % hash->csize; 781 idx = idx % hash->csize;
775 hi->next = hash->items[idx]; 782 hi->next = hash->items[idx];
776 hash->items[idx] = hi; 783 hash->items[idx] = hi;
777 hash->glen += l; 784 hash->glen += l;
@@ -822,8 +829,10 @@ static char *skip_spaces(char *p)
822static char *nextword(char **s) 829static char *nextword(char **s)
823{ 830{
824 char *p = *s; 831 char *p = *s;
825 while (*(*s)++ != '\0') 832 char *q = p;
833 while (*q++ != '\0')
826 continue; 834 continue;
835 *s = q;
827 return p; 836 return p;
828} 837}
829 838
@@ -2116,8 +2125,7 @@ static void hashwalk_init(var *v, xhash *array)
2116 for (i = 0; i < array->csize; i++) { 2125 for (i = 0; i < array->csize; i++) {
2117 hi = array->items[i]; 2126 hi = array->items[i];
2118 while (hi) { 2127 while (hi) {
2119 strcpy(w->end, hi->name); 2128 w->end = stpcpy(w->end, hi->name) + 1;
2120 nextword(&w->end);
2121 hi = hi->next; 2129 hi = hi->next;
2122 } 2130 }
2123 } 2131 }
@@ -3504,7 +3512,7 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
3504 setari_u(intvar[ARGV], ++i, *argv++); 3512 setari_u(intvar[ARGV], ++i, *argv++);
3505 setvar_i(intvar[ARGC], i + 1); 3513 setvar_i(intvar[ARGC], i + 1);
3506 3514
3507 //fdhash = ahash - done via define 3515 //fdhash = ahash; // done via define
3508 newfile("/dev/stdin")->F = stdin; 3516 newfile("/dev/stdin")->F = stdin;
3509 newfile("/dev/stdout")->F = stdout; 3517 newfile("/dev/stdout")->F = stdout;
3510 newfile("/dev/stderr")->F = stderr; 3518 newfile("/dev/stderr")->F = stderr;