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>
This commit is contained in:
parent
b3c91a127f
commit
3aff3b9cb8
@ -696,6 +696,7 @@ static void hash_clear(xhash *hash)
|
|||||||
while (hi) {
|
while (hi) {
|
||||||
thi = hi;
|
thi = hi;
|
||||||
hi = hi->next;
|
hi = hi->next;
|
||||||
|
//FIXME: this assumes that it's a hash of *variables*:
|
||||||
free(thi->data.v.string);
|
free(thi->data.v.string);
|
||||||
free(thi);
|
free(thi);
|
||||||
}
|
}
|
||||||
@ -714,11 +715,11 @@ static void hash_free(xhash *hash)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* find item in hash, return ptr to data, NULL if not found */
|
/* find item in hash, return ptr to data, NULL if not found */
|
||||||
static void *hash_search(xhash *hash, const char *name)
|
static NOINLINE void *hash_search3(xhash *hash, const char *name, unsigned idx)
|
||||||
{
|
{
|
||||||
hash_item *hi;
|
hash_item *hi;
|
||||||
|
|
||||||
hi = hash->items[hashidx(name) % hash->csize];
|
hi = hash->items[idx % hash->csize];
|
||||||
while (hi) {
|
while (hi) {
|
||||||
if (strcmp(hi->name, name) == 0)
|
if (strcmp(hi->name, name) == 0)
|
||||||
return &hi->data;
|
return &hi->data;
|
||||||
@ -727,6 +728,11 @@ static void *hash_search(xhash *hash, const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *hash_search(xhash *hash, const char *name)
|
||||||
|
{
|
||||||
|
return hash_search3(hash, name, hashidx(name));
|
||||||
|
}
|
||||||
|
|
||||||
/* grow hash if it becomes too big */
|
/* grow hash if it becomes too big */
|
||||||
static void hash_rebuild(xhash *hash)
|
static void hash_rebuild(xhash *hash)
|
||||||
{
|
{
|
||||||
@ -762,16 +768,17 @@ static void *hash_find(xhash *hash, const char *name)
|
|||||||
unsigned idx;
|
unsigned idx;
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
hi = hash_search(hash, name);
|
idx = hashidx(name);
|
||||||
|
hi = hash_search3(hash, name, idx);
|
||||||
if (!hi) {
|
if (!hi) {
|
||||||
if (++hash->nel / hash->csize > 10)
|
if (++hash->nel > hash->csize * 8)
|
||||||
hash_rebuild(hash);
|
hash_rebuild(hash);
|
||||||
|
|
||||||
l = strlen(name) + 1;
|
l = strlen(name) + 1;
|
||||||
hi = xzalloc(sizeof(*hi) + l);
|
hi = xzalloc(sizeof(*hi) + l);
|
||||||
strcpy(hi->name, name);
|
strcpy(hi->name, name);
|
||||||
|
|
||||||
idx = hashidx(name) % hash->csize;
|
idx = idx % hash->csize;
|
||||||
hi->next = hash->items[idx];
|
hi->next = hash->items[idx];
|
||||||
hash->items[idx] = hi;
|
hash->items[idx] = hi;
|
||||||
hash->glen += l;
|
hash->glen += l;
|
||||||
@ -822,8 +829,10 @@ static char *skip_spaces(char *p)
|
|||||||
static char *nextword(char **s)
|
static char *nextword(char **s)
|
||||||
{
|
{
|
||||||
char *p = *s;
|
char *p = *s;
|
||||||
while (*(*s)++ != '\0')
|
char *q = p;
|
||||||
|
while (*q++ != '\0')
|
||||||
continue;
|
continue;
|
||||||
|
*s = q;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2116,8 +2125,7 @@ static void hashwalk_init(var *v, xhash *array)
|
|||||||
for (i = 0; i < array->csize; i++) {
|
for (i = 0; i < array->csize; i++) {
|
||||||
hi = array->items[i];
|
hi = array->items[i];
|
||||||
while (hi) {
|
while (hi) {
|
||||||
strcpy(w->end, hi->name);
|
w->end = stpcpy(w->end, hi->name) + 1;
|
||||||
nextword(&w->end);
|
|
||||||
hi = hi->next;
|
hi = hi->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3504,7 +3512,7 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
setari_u(intvar[ARGV], ++i, *argv++);
|
setari_u(intvar[ARGV], ++i, *argv++);
|
||||||
setvar_i(intvar[ARGC], i + 1);
|
setvar_i(intvar[ARGC], i + 1);
|
||||||
|
|
||||||
//fdhash = ahash - done via define
|
//fdhash = ahash; // done via define
|
||||||
newfile("/dev/stdin")->F = stdin;
|
newfile("/dev/stdin")->F = stdin;
|
||||||
newfile("/dev/stdout")->F = stdout;
|
newfile("/dev/stdout")->F = stdout;
|
||||||
newfile("/dev/stderr")->F = stderr;
|
newfile("/dev/stderr")->F = stderr;
|
||||||
|
Loading…
Reference in New Issue
Block a user