diff options
author | Tony Cook <tony@develop-help.com> | 2020-02-26 09:51:25 +1100 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2020-03-02 09:50:48 -0700 |
commit | 0bd6eef439e2cdb97b9b64430c17d4f523f75914 (patch) | |
tree | 31bd80d2f25aa6f6f59d56ee498df7ce94e62730 /op.h | |
parent | 0069caf1227609b76a39fd52b9e60cf9385c68f1 (diff) | |
download | perl-0bd6eef439e2cdb97b9b64430c17d4f523f75914.tar.gz |
make freed op re-use closer to O(1)
previously freed ops were stored as one singly linked list, and
a failed search for a free op to re-use could potentially search
that entire list, making freed op lookups O(number of freed ops),
or given that the number of freed ops is roughly proportional to
program size, making the total cost of freed op handling roughly
O((program size)**2). This was bad.
This change makes opslab_freed into an array of linked list heads,
one per op size. Since in a practical sense the number of op sizes
should remain small, and insertion is amortized O(1), this makes
freed op management now roughly O(program size).
fixes #17555
Diffstat (limited to 'op.h')
-rw-r--r-- | op.h | 3 |
1 files changed, 2 insertions, 1 deletions
@@ -703,8 +703,9 @@ struct opslot { struct opslab { OPSLAB * opslab_next; /* next slab */ OPSLAB * opslab_head; /* first slab in chain */ - OP * opslab_freed; /* chain of freed ops (head only)*/ + OP ** opslab_freed; /* array of sized chains of freed ops (head only)*/ size_t opslab_refcnt; /* number of ops (head slab only) */ + U16 opslab_freed_size; /* allocated size of opslab_freed */ U16 opslab_size; /* size of slab in pointers, including header */ U16 opslab_free_space; /* space available in this slab |