Procesos de trabajo paralelos
Greph distribuye los análisis de texto y AST entre varios procesos de trabajo cuando el volumen justifica el coste adicional. El grupo se basa en pcntl_fork() y recurre a la ejecución dentro del proceso cuando ext-pcntl no está disponible (Windows, algunos entornos PaaS y alojamientos restringidos).
Activar análisis paralelos
Defina -j N en CLI o jobs: N en el objeto de opciones correspondiente:
./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),
);
Cuándo se activa el procesamiento paralelo
Greph no paraleliza todas las tareas. Crear N procesos y enviar sus resultados de ida y vuelta por tuberías tiene un coste; con listas pequeñas de archivos, ese coste supera el de la búsqueda. En su lugar, la fachada calcula un umbral según el número de tareas, el modo de búsqueda y la forma del patrón. Solo se envían al grupo las listas de archivos que superan el umbral.
Las heurísticas actuales (en Greph\Greph::shouldUseTextWorkers y elementos relacionados):
- Las ejecuciones de una sola tarea (
-j 1) siempre se realizan dentro del proceso. - Los análisis de texto predeterminados requieren aproximadamente
jobs * 2_000archivos para activar el grupo. - Los modos de recuento, archivos con coincidencias y archivos sin coincidencias reducen el umbral a aproximadamente
jobs * 750porque el trabajo por archivo es menor. - Los patrones de cadena fija cortos con forma de identificador elevan el umbral a aproximadamente
jobs * 4_000, ya que la ruta rápida de búsqueda literal ya es tan barata que rara vez compensa crear procesos. - La búsqueda y reescritura de AST usan el umbral
jobs * 750.
Estas cifras son heurísticas, no garantías. Se ajustan con el corpus de pruebas de rendimiento WordPress y pueden revisarse.
Cómo funciona el grupo
Greph\Parallel\WorkSplitter distribuye la lista de archivos en N fragmentos. Greph\Parallel\WorkerPool crea un proceso de trabajo por fragmento; cada proceso ejecuta la misma función en su parte, y Greph\Parallel\ResultCollector lee los resultados serializados mediante un par de sockets Unix por proceso. El proceso principal espera a que terminen todos y luego combina y vuelve a ordenar los resultados para que el orden de salida sea estable, independientemente de cómo se haya dividido el trabajo.
En el modo de texto, el grupo de procesos usa un códec personalizado para la transmisión (Greph\Text\TextResultCodec) que mantiene compacto el contenido serializado. El modo AST usa el serialize() estándar de PHP.
Cuando pcntl no está disponible
Si no se puede llamar a pcntl_fork (Windows, compilaciones reforzadas de PHP), el grupo recurre de forma transparente a ejecutar cada fragmento dentro del proceso. El resultado es el mismo que con -j 1. Greph no genera ningún error; simplemente se ejecuta con un solo proceso.
Puede detectarlo durante la ejecución comprobando function_exists('pcntl_fork').
Consejos de ajuste
- Empiece con
-jestablecido en la mitad del número de núcleos físicos y auméntelo hasta que dejen de mejorar los resultados. - Para búsquedas de cadenas fijas que solo usan literales en repositorios pequeños, un solo proceso suele ser más rápido que cualquier configuración paralela.
- Ninguna prueba de rendimiento publicada mide la búsqueda o reescritura de AST en paralelo. Mida el rendimiento en su propio árbol antes de elegir el número de tareas.
- Las filas «Modo de análisis: texto paralelo» de README (
1,2y4procesos de trabajo en el corpus WordPress) no miden el grupo: buscan el literal cortofunction, cuyo umbral dejobs * 4_000archivos supera el tamaño del corpus, así que todas las filas se ejecutan dentro de un solo proceso (#8).
Limitaciones
- El grupo actual no admite el robo de trabajo. Si un fragmento tiene mucha más carga que los demás, el grupo espera al proceso más lento.
- Los resultados de los procesos de trabajo se almacenan en búfer hasta que todos terminan. El modo paralelo no admite la salida en flujo de un análisis prolongado (como la transmisión de eventos de
rg --json). - El proceso principal vuelve a ordenar los resultados después de combinarlos, por lo que el grupo no reduce el uso máximo de memoria frente a un análisis de un solo proceso.
Estas limitaciones son aceptables para las cargas de trabajo a las que apunta Greph (búsqueda interactiva de código, ciclos de agentes y trabajos de CI sobre instantáneas). Se revisarán si el perfilado muestra que son un cuello de botella en corpus reales.