Gå til indhold

Parallelle arbejdere

Greph fordeler tekst- og AST-scanninger på en worker-pulje, når arbejdsmængden er stor nok til at retfærdiggøre overheaden. Puljen er baseret på pcntl_fork() og falder tilbage til kørsel i samme proces, når ext-pcntl ikke er tilgængelig (Windows, visse PaaS-miljøer, begrænset hosting).

Aktivér parallel scanning

Angiv -j N på CLI eller jobs: N i det relevante options-objekt:

Shell
./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
PHP
use Greph\Greph;
use Greph\Text\TextSearchOptions;

Greph::searchText(
    'function',
    'src',
    new TextSearchOptions(fixedString: true, jobs: 8),
);

Hvornår parallelisering starter

Greph paralleliserer ikke altid. Det kræver ressourcer at forgrene N processer og sende deres resultater frem og tilbage gennem pipes, og ved små fillister overstiger denne omkostning selve søgningen. I stedet beregner facaden en tærskel ud fra antallet af job, søgetilstanden og mønsterets form. Kun fillister over tærsklen fordeles til worker-puljen.

De aktuelle heuristikker (i Greph\Greph::shouldUseTextWorkers og beslægtede funktioner):

  • Kørsel med ét job (-j 1) foregår altid i samme proces.
  • Standardscanning af tekst kræver cirka jobs * 2_000 filer, før puljen aktiveres.
  • Tilstandene antal, filer med match og filer uden match sænker tærsklen til cirka jobs * 750, fordi arbejdet pr. fil er mindre.
  • Korte mønstre af faste strenge, der ligner identifikatorer, hæver tærsklen til cirka jobs * 4_000, fordi den hurtige bogstavelige søgevej allerede er så billig, at forgrening sjældent kan betale sig.
  • AST-søgning og AST-omskrivning bruger tærsklen jobs * 750.

Disse tal er heuristikker, ikke løfter. De er tilpasset benchmark-datasættet WordPress og kan blive justeret.

Sådan fungerer puljen

Greph\Parallel\WorkSplitter fordeler fillisten på N dele. Greph\Parallel\WorkerPool forgrener én worker-proces pr. del; hver worker kører den samme closure på sin del, og Greph\Parallel\ResultCollector læser de serialiserede resultater via et Unix-socketpar pr. worker. Forældreprocessen venter på alle workers og sammenfletter derefter resultaterne og sorterer dem igen, så rækkefølgen i outputtet er stabil, uanset hvordan arbejdet blev fordelt.

I teksttilstand bruger worker-puljen en tilpasset codec til overførsel (Greph\Text\TextResultCodec) for at holde den serialiserede payload kompakt. AST-tilstand bruger PHPs standard-serialize().

Når pcntl ikke er tilgængelig

Hvis pcntl_fork ikke kan kaldes (Windows, hærdede PHP-builds), falder puljen automatisk tilbage til at køre hver del i samme proces. Resultatet er det samme som med -j 1. Greph udløser ikke en fejl; det kører blot med én tråd.

Du kan registrere dette ved kørsel ved at kontrollere function_exists('pcntl_fork').

Råd om justering

  • Start med -j sat til halvdelen af antallet af fysiske kerner, og øg værdien, indtil forbedringerne udebliver.
  • Ved søgning udelukkende efter bogstavelige faste strenge i små repositories er kørsel i én proces som regel hurtigere end enhver parallel konfiguration.
  • Ingen offentliggjorte benchmarks måler parallel AST-søgning eller -omskrivning. Mål på dit eget træ, før du vælger antal job.
  • Rækkerne »Scan Mode: Parallel Text« i README (1, 2 og 4 workers på datasættet WordPress) måler ikke puljen: de søger efter den korte bogstavelige streng function, hvis tærskel på jobs * 4_000 filer er større end datasættet. Derfor køres alle rækker i samme proces (#8).

Begrænsninger

  • Den aktuelle pulje understøtter ikke work stealing. Hvis en del er betydeligt tungere end de andre, venter puljen på den langsomste worker.
  • Worker-resultaterne buffres, indtil alle workers er færdige. Streaming af output fra en langvarig scanning (som rg --json streamer hændelser) understøttes ikke i parallel tilstand.
  • Forældreprocessen sorterer resultaterne igen efter sammenfletning, så worker-puljen reducerer ikke det maksimale hukommelsesforbrug sammenlignet med scanning i én proces.

Disse begrænsninger er acceptable for de arbejdsbelastninger, Greph er beregnet til (interaktiv kodesøgning, agentforløb og CI-jobs på øjebliksbilleder). De bliver taget op igen, hvis profilering viser, at de er en flaskehals på virkelige datasæt.