From 6ecc7cab99f82ae67db49a8bdd5e7be69e1480c2 Mon Sep 17 00:00:00 2001 From: Josh Davies Date: Wed, 9 Sep 2026 23:35:53 +0100 Subject: [PATCH] perf: improve TFORM CopySpectator performance CopySpectator creates a one-term prototype expression in the scratch file. We must not use this to determine TFORM bucket size, or the master will create an enormous number of single-term buckets for the workers. Additionally, now that we properly enter the bucket-filling loop, we need to call GetFromSpectator instead of GetTermP. --- sources/threads.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sources/threads.c b/sources/threads.c index 4aab3064..ebdc5506 100644 --- a/sources/threads.c +++ b/sources/threads.c @@ -2667,7 +2667,11 @@ int ThreadsProcessor(EXPRESSIONS e, WORD LastExpression, WORD fromspectator) The number of terms in the expression is in e->counter */ thrbufsiz2 = thrbufsiz = AC.ThreadBucketSize-1; - if ( ( e->counter / ( numberofworkers * 5 ) ) < thrbufsiz ) { + /* CopySpectator expressions have a one-term expression prototype in the + * scratch file, regardless of how many terms the spectator contains. Don't + * use this prototype to determine bucket size, or we'll end up with single-term + * buckets and bad performance. Just use thrbufsiz in this case. */ + if ( ! fromspectator && ( e->counter / ( numberofworkers * 5 ) ) < thrbufsiz ) { thrbufsiz = e->counter / ( numberofworkers * 5 ) - 1; if ( thrbufsiz < 0 ) thrbufsiz = 0; } @@ -2922,7 +2926,9 @@ Found2:; /* There is room in the bucket. Fill yet another term. */ - if ( GetTermP(B0,tt) == 0 ) { endofinput = 1; break; } + if ( ( fromspectator + ? GetFromSpectator(tt,fromspectator-1) + : GetTermP(B0,tt) ) == 0 ) { endofinput = 1; break; } dd++; thr->totnum++; dd += AN0.deferskipped; @@ -2973,7 +2979,9 @@ Found2:; /* There is room in the bucket. Fill yet another term. */ - if ( GetTermP(B0,tt) == 0 ) { endofinput = 1; break; } + if ( ( fromspectator + ? GetFromSpectator(tt,fromspectator-1) + : GetTermP(B0,tt) ) == 0 ) { endofinput = 1; break; } /* Same bracket? */