From 3777d9a6b4f886dcc37fce9aa16038d5fcbc5dc5 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 22 Mar 2026 14:16:37 -0400 Subject: [PATCH] Improve speed of find_close_polyvertex in debug builds for #226 --- src/hardware/hw_map.c | 67 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/src/hardware/hw_map.c b/src/hardware/hw_map.c index f70457ebf..7a78f60f9 100644 --- a/src/hardware/hw_map.c +++ b/src/hardware/hw_map.c @@ -130,16 +130,46 @@ static polyvertex_t *find_close_polyvertex(float x, float y, float ep) { polyvertex_store_t *psv; polyvertex_t *pv; + float dx, dy; INT32 i; + // eep! + const float eep = ep*ep; + + // we do some lööp unrollin + // those checks stink in debug builds and take literal ages + // unrolling the loops to check 8 at a time with extra early rejects + // cuts the total time by around 54% on my maschine + +#define CHECKVERTEX(p) \ + dx = (p)->x - x; \ + /* reject vertices that are waaay off by checking in a square */ \ + if (!(dx < -ep || dx > ep)) { \ + dy = (p)->y - y; \ + if (!(dy < -ep || dy > ep)) \ + if (dx*dx + dy*dy < eep) /* close enough to be the same vertex */ \ + return (p); \ + } + // Search level map vertexes. pv = poly_vert; - for (i = numvertexes; i > 0; i--) + for (i = numvertexes; i >= 8; i -= 8) { - const float dx = pv->x - x; - const float dy = pv->y - y; - if (dx*dx + dy*dy < ep*ep) - return pv; // close enough to be the same vertex + CHECKVERTEX(pv); + CHECKVERTEX(pv + 1); + CHECKVERTEX(pv + 2); + CHECKVERTEX(pv + 3); + CHECKVERTEX(pv + 4); + CHECKVERTEX(pv + 5); + CHECKVERTEX(pv + 6); + CHECKVERTEX(pv + 7); + + pv += 8; + } + + for (; i > 0; i--) + { + CHECKVERTEX(pv); pv++; } @@ -147,20 +177,33 @@ static polyvertex_t *find_close_polyvertex(float x, float y, float ep) psv = polyvert_store; while (psv) { - // Search all vertex in a polyvertex_store_t pv = psv->pv; - for (i = psv->num_vert_used; i > 0; i--) + for (i = psv->num_vert_used; i >= 8; i -= 8) { - const float dx = pv->x - x; - const float dy = pv->y - y; - if (dx*dx + dy*dy < ep*ep) - return pv; // close enough to be the same vertex + CHECKVERTEX(pv); + CHECKVERTEX(pv + 1); + CHECKVERTEX(pv + 2); + CHECKVERTEX(pv + 3); + CHECKVERTEX(pv + 4); + CHECKVERTEX(pv + 5); + CHECKVERTEX(pv + 6); + CHECKVERTEX(pv + 7); + + pv += 8; + } + + for (; i > 0; i--) + { + CHECKVERTEX(pv); pv++; } + psv = psv->next; } +#undef CHECKVERTEX - return NULL; // none found + // none found + return NULL; } // Store a new polyvertex.