Parallella arbetare
Greph fördelar text- och AST-sökningar över en arbetarpool när arbetet är tillräckligt omfattande för att motivera omkostnaden. Poolen bygger på pcntl_fork() och går över till körning i samma process när ext-pcntl inte är tillgängligt (Windows, vissa PaaS-miljöer och begränsade värdmiljöer).
Aktivera parallella sökningar
Ange -j N på CLI eller jobs: N i det relevanta optionsobjektet:
./vendor/bin/greph -F -j 8 "function" src
./vendor/bin/greph -p '$obj->$method($$$ARGS)' -j 4 src
./vendor/bin/rg --threads 8 -F "function" src
./vendor/bin/sg run --threads 8 --pattern '$obj->$method($$$ARGS)' src
use Greph\Greph;
use Greph\Text\TextSearchOptions;
Greph::searchText(
'function',
'src',
new TextSearchOptions(fixedString: true, jobs: 8),
);
När parallell körning aktiveras
Greph parallelliserar inte villkorslöst. Att förgrena N processer och skicka deras resultat fram och tillbaka via rör medför en kostnad, och för små fillistor överstiger den kostnaden själva sökningen. I stället beräknar fasaden en tröskel utifrån antalet jobb, sökläget och mönstrets form. Endast fillistor som överskrider tröskeln skickas till arbetarpoolen.
De aktuella heuristikerna (i Greph\Greph::shouldUseTextWorkers och närliggande kod):
- Körningar med ett jobb (
-j 1) körs alltid i samma process. - Standardsökningar i text kräver ungefär
jobs * 2_000filer innan poolen aktiveras. - Lägena för antal träffar, filer med träffar och filer utan träffar sänker tröskeln till ungefär
jobs * 750eftersom arbetet per fil är billigare. - Korta mönster med fast sträng som liknar identifierare höjer tröskeln till ungefär
jobs * 4_000eftersom den snabba vägen för bokstavliga strängar redan är så billig att förgrening sällan lönar sig. - AST-sökning och AST-omskrivning använder tröskeln
jobs * 750.
Dessa tal är heuristiker, inte garantier. De är finjusterade mot benchmarkkorpusen WordPress och kan komma att ses över.
Så fungerar poolen
Greph\Parallel\WorkSplitter fördelar fillistan i N delar. Greph\Parallel\WorkerPool förgrenar en arbetarprocess per del. Varje arbetare kör samma closure på sin del, och Greph\Parallel\ResultCollector läser tillbaka de serialiserade resultaten via ett Unix-socketpar per arbetare. Den överordnade processen väntar på alla arbetare och sammanfogar sedan resultaten och sorterar dem igen, så att utdataordningen är stabil oavsett hur arbetet delades upp.
För textläget använder arbetarpoolen en anpassad codec på tråden (Greph\Text\TextResultCodec) för att hålla den serialiserade nyttolasten liten. AST-läget använder standardlösningen serialize() från PHP.
När pcntl inte är tillgängligt
Om pcntl_fork inte kan anropas (Windows, härdade byggen av PHP) går poolen sömlöst över till att köra varje del i samma process. Resultatet är detsamma som för -j 1. Greph ger inget fel utan körs bara med en tråd.
Du kan upptäcka detta vid körning genom att kontrollera function_exists('pcntl_fork').
Råd för finjustering
- Börja med att ange
-jtill hälften av antalet fysiska kärnor och höj värdet tills förbättringarna uteblir. - För sökningar med enbart bokstavliga fasta strängar i små arkiv är en enda process oftast snabbare än alla parallella konfigurationer.
- Inget publicerat prestandatest mäter parallell AST-sökning eller omskrivning. Mät på ditt eget träd innan du bestämmer antalet jobb.
- Raderna ”Sökläge: parallell text” i README (
1,2och4arbetare på korpusen WordPress) mäter inte poolen: de söker efter den korta bokstavliga strängenfunction, vars tröskel påjobs * 4_000filer överstiger korpusens storlek, så varje rad körs i samma process (#8).
Begränsningar
- Den aktuella poolen stöder inte arbetsstöld. Om en del är mycket tyngre än de andra väntar poolen på den långsammaste arbetaren.
- Arbetarresultaten buffras tills alla arbetare är klara. Strömmande utdata från en långvarig sökning (som när
rg --jsonströmmar händelser) stöds inte i parallellt läge. - Den överordnade processen sorterar om resultaten efter sammanslagningen, så arbetarpoolen minskar inte toppminnesanvändningen jämfört med en genomsökning i en enda process.
Dessa begränsningar är acceptabla för de arbetsbelastningar som Greph riktar sig till (interaktiv kodsökning, agentloopar och CI-jobb över ögonblicksbilder). De ses över om profilering visar att de är en flaskhals på verkliga korpusar.