Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Performance: skip parsing files that no advisor or node rewriter can affect (~90% of files on a cold cache)

Aperta
#747 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
35/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
php
Ambito
performance

Direzione di ricerca

Start in plan mode, as the issue requires an approved design before implementation. Read src/Instrument/Transformer/StreamMetaData.php, SyntaxTreeRewriter, WeavingTransformer, and the pointcut and cache-map APIs; first settle where the pre-check belongs and how unknown match cases and custom transformers veto skipping. Done means tests show unchanged woven output and cache maps against full parsing, with warmup and composer test:performance:transformation benchmarks before and after.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Enhancement Performance

Implementation note: start in plan mode. The pointcut-side API and the fallback rules need an approved design before any code is written.

Problem

On a cache miss, StreamMetaData always parses the full file with php-parser plus a NameResolver pass (src/Instrument/Transformer/StreamMetaData.php:134), before any transformer can decide it has nothing to do.

SyntaxTreeRewriter already skips its tree walk when no rule marker is present (#736). The parse itself is never skipped, and WeavingTransformer then reflects every class against every advisor. In typical setups the pointcuts select classes by namespace or name, so most files are parsed for nothing.

Measurement

Cold cache:warmup:aop over vendor/ (3,935 files, 14 MB of source). Two advisors: execution(public Symfony\Component\Console\Command\**->*(*)) and execution(public Doctrine\ORM\**->*(*)). PHP 8.5, JIT off.

phase time
StreamMetaData (parse + NameResolver) 6.2 s (67%)
WeavingTransformer 2.3 s
SyntaxTreeRewriter 0.07 s
cache writes + flush 0.16 s
  • Only 393 of 3,935 files (10%) were transformed.
  • Tokenizing all files with PhpToken::tokenize() takes 0.2 s, against about 4 s for the parse alone.

Proposal (to be refined in plan mode)

Before the parse, do a cheap pre-check on the raw source:

  1. Tokenize, or use another cheap scan, to extract the namespaces and the declared class, trait and enum names (and function names when INTERCEPT_FUNCTIONS is on).
  2. Ask each advisor whether it could match the declared names. Add an internal, optional capability on pointcuts, for example "decide by name only", which returns yes, no or unknown.
    • Name-based class filters and namespace filters answer definitively.
    • Inheritance (Foo+), attribute filters (@within, @execution), ! combinations and custom pointcuts answer "unknown", which forces a full parse.
  3. Skip the parse only when no advisor can match and no PrefilteredNodeRewriter marker is present (the same check SyntaxTreeRewriter does today). In that case, record the file as untransformed, including its class names for the skip map (CachePathManager::registerClassForResource()), and serve the source as is.

Open questions for the plan

  • Where the pre-check lives: SourceTransformingLoader, a new first stage, or a SourceTransformer capability. Custom transformers registered through registerTransformerServices() must be able to opt out of, or veto, the skip.
  • Exact semantics of "could match" for ||, && and !, and for within(**)-style wildcards.
  • Introductions and INTERCEPT_INITIALIZATIONS / INTERCEPT_INCLUDES markers.
  • Interaction with aspects that are first loaded on the miss path (getUnloadedAspects()).

Acceptance

  • No change in the woven output and no change in the cache maps compared with full parsing. A test should prove this over the fixture project and a larger corpus.
  • Warmup benchmark before and after.
  • composer test:performance:transformation before and after.

Estimate

Cold warmup about 9 s → 3–4 s (estimated) for configurations with name-based pointcuts. No gain, and no regression, for configurations with inheritance or attribute pointcuts. Medium to high risk, large change.

Lingua principale
PHP
Stelle
1.7k
Fork
166
Merge medio
20h 56m
PR unite (30g)
45

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di goaop/framework

Tutte le issue di goaop/framework

Issue simili

Altre issue su PHP

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.