From 3e472599d8a9e695834d9581c23b1266981a1351 Mon Sep 17 00:00:00 2001 From: Iti Shree Date: Thu, 21 Mar 2024 14:42:56 +0000 Subject: [PATCH] Optimise the YkLocation buffer. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Location array was reallocated for every instructions, which was very ineffective since we only need to reallocate the buffer either when yk location is set to NULL or when the number of bytecode instructions is greater than number of location in the yk location array. This was causing around 200x slowdown in benchmark test such as `verybig.lua`. The fix fetches the performance back by only reallocting when we need to. ---------------------------------------------------------- |Performance of benchmark numbers before and after the fix | ---------------------------------------------------------- | db.lua | 0.146 ± 0.003 | 0.127 ± 0.00 ---------------------------------------------------------- | fasta.lua | 3.798 ± 0.006 | 3.771 ± 0.002 ---------------------------------------------------------- | verybig.lua | 198.046 ± 1.06 | 0.638 ± 0.004 --------------------------------------------------------- |construct.lua| 4.999 ± 0.003 | 4.585 ± 0.003 -------------------------------------------------------- | gc.lua | 0.485 ± 0.009 | 0.467 ± 0.006 --- src/lyk.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/lyk.c b/src/lyk.c index 6b602c6..3255c2b 100644 --- a/src/lyk.c +++ b/src/lyk.c @@ -92,23 +92,24 @@ void set_location(Proto *f, int i) { } inline void yk_on_instruction_loaded(Proto *f, Instruction i, int idx) { - // YKOPT: Reallocating for every instruction is inefficient. - YkLocation **new_locations = calloc(f->sizecode, sizeof(YkLocation *)); - lua_assert(new_locations != NULL && "Expected yklocs to be defined!"); + if (f->yklocs == NULL) { + // Allocate initial array + f->yklocs = calloc(f->sizecode, sizeof(YkLocation *)); + lua_assert(f->yklocs != NULL && "Expected yklocs to be defined!"); + f->yklocs_size = f->sizecode; + } else if (f->sizecode > f->yklocs_size) { + // Extend the array + YkLocation **new_locations = + realloc(f->yklocs, f->sizecode * sizeof(YkLocation *)); + lua_assert(new_locations != NULL && "Expected yklocs to be defined!"); - // copy previous locations over - if (f->yklocs != NULL) { - for (int i = 0; i < f->yklocs_size; i++) { - if (f->yklocs[i] != NULL) { - new_locations[i] = f->yklocs[i]; - } else { - new_locations[i] = NULL; - } + for (int i = f->yklocs_size; i < f->sizecode; i++) { + new_locations[i] = NULL; } - free(f->yklocs); + + f->yklocs = new_locations; + f->yklocs_size = f->sizecode; } - f->yklocs = new_locations; - f->yklocs_size = f->sizecode; if (is_loop_start(i)) { set_location(f, idx); }