Improve Data hot-path performance with automatic execution recipes - #31
Improve Data hot-path performance with automatic execution recipes#31binaryfire wants to merge 6 commits into
Conversation
Extract the built-in, backed-enum, and date conversion rules into one internal ValueCaster used by both ordinary casts and lean construction recipes. This keeps coercion behavior, date formats and timezones, concrete date targets, and existing exception contracts in one authoritative implementation without retaining cast instances in worker metadata.
Compile immutable per-class construction and transformation recipes from existing Data metadata, then select them automatically for supported runtime shapes while preserving the general engine as the single fallback. Reuse immutable default creation contexts, preflight complete nodes before conversion, share nested operation state, retain named-factory and hook boundaries, and keep bulk-copy transformation for plain objects. Unsupported declarations and ambiguous conversion families continue through the established path before construction. Defer PHPDoc parser setup when native types prove iterable metadata cannot apply. Add focused equivalence, fallback, metadata, lazy, partial, mapping, constructor, and transformation coverage so lean execution stays behaviorally identical to the general path.
Resolve DataCreator and DataTransformer from an application booted callback after all providers have configured their dependencies. Production workers inherit the initialized immutable service graph instead of making the first request pay that fixed setup cost. Keep unit-test applications on demand so repeated Testbench boots remain fast, and cover both testing and non-testing application lifecycles with stable instance assertions.
Expand the developer benchmark matrix across construction, validation, transformation, collections, resources, persistence, metadata, and first-use boundaries. Add a dedicated historical DataObject comparison harness under the test namespace so supported shapes can be measured against the removed mapper without restoring it as framework API. Document both commands and keep raw reports opt-in and outside the repository.
Record the measured baseline, immutable recipe design, one-engine fallback rules, lifecycle constraints, integration boundaries, test matrix, performance acceptance criteria, and rejected alternatives. The plan also preserves the required post-checkpoint merge and benchmark work so the current 0.4 enum and morph behavior is reconciled before final integration.
Bring the latest 0.4 framework changes into the automatic Data execution branch, including the first-party FormRequest casting redesign, shared enum coercion helpers, and the queue, database, validation, and lifecycle fixes already accepted on 0.4. Reconcile the Data fast path with the shared enum_from semantics so lean and general construction accept integer-backed numeric strings consistently. Preserve enum_try_from morph selection and add a focused regression that proves the compiled operation, target enum, and concrete result. Finish the execution terminology sweep, retain the measured performance and memory conclusions in the active plan, and record the completed verification state. The merged tree passes composer fix and focused Data, enum, FormRequest, and capability coverage; repeated benchmarks retain the material construction and transformation gains without a systematic fallback-path regression.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR adds metadata-compiled construction and transformation recipes for eligible Data declarations while preserving the general engine as the fallback.
Confidence Score: 5/5The PR appears safe to merge, with optimized paths narrowly gated and unsupported behavior continuing through the established general engine. No actionable correctness, security, or repository-rule violations remained after tracing recipe compilation and execution through construction, transformation, annotation parsing, service boot, and benchmark subprocess handling.
|
| Filename | Overview |
|---|---|
| src/data/src/Support/Creation/DataCreator.php | Adds preflighted recipe construction, default-context caching, shared nested operation state, and single-pass named-factory fallback without an identified contract regression. |
| src/data/src/Support/Factories/DataClassFactory.php | Compiles bounded creation/transformation recipes and conservatively screens PHPDoc parsing while retaining unsupported declarations on the general path. |
| src/data/src/Support/Factories/DataPropertyFactory.php | Classifies fixed property operations according to the existing conversion priority and excludes ambiguous transformation targets. |
| src/data/src/Support/Transformation/DataTransformer.php | Adds guarded fixed-recipe transformation alongside the existing bulk and general paths while preserving finalization and nested partial handling. |
| src/data/src/Support/Creation/ValueCaster.php | Centralizes built-in, enum, and date conversion behavior previously implemented by the individual cast adapters. |
| src/data/src/Support/Creation/CreationContextFactory.php | Reuses immutable Create contexts and invalidates them consistently across every fluent factory mutation. |
| src/data/src/Support/Annotations/DataIterableAnnotationReader.php | Defers parser construction until an eligible PHPDoc comment is actually parsed. |
| src/data/src/DataServiceProvider.php | Resolves the fixed creator and transformer graph after production application boot while leaving unit-test startup lazy. |
| tests/Benchmarks/Data/compare-data-object.php | Adds an isolated historical comparison harness whose subprocess command uses escaped, fixed inputs. |
| tests/Data/Support/Creation/DataCreatorTest.php | Adds extensive lean/general equivalence, fallback, factory, conversion, lazy replay, and side-effect-order coverage. |
| tests/Data/Support/Transformation/DataTransformerTest.php | Verifies fixed-recipe equivalence and guards around bulk copy, custom transformations, iterables, partials, and persistence. |
Reviews (1): Last reviewed commit: "Merge 0.4 into Data lean execution" | Re-trigger Greptile
Summary
This change makes common
hypervel/dataconstruction and transformation paths substantially faster without adding a second data-object API or changing the public contract.Data classes now receive immutable execution recipes when their declarations can be handled safely by fixed operations. The runtime selects those recipes automatically. Classes using custom casts, normalizers, lifecycle hooks, validation, lazy values, partials, or unsupported union shapes continue through the existing general engine.
Motivation
The Data package supports validation, property mapping, nested objects and collections, lazy values, partial transformations, HTTP resources, request casting, and Eloquent persistence. Its general engine preserves all of those behaviors, but simple objects were paying much of that orchestration cost even when their declarations needed only fixed scalar, enum, date, or nested Data conversion.
The goal here is to make work proportional to the features a declaration uses. Applications should not need to choose a fast mode or a separate lightweight object type.
Design
Class metadata now records one of three transformation states: bulk copy, a fixed property recipe, or the general property loop. Construction similarly records a fixed recipe only for declarations whose behavior is known at metadata-build time.
The implementation:
ValueCaster, keeping lean and general behavior identical;factory()overrides, validation decisions, partials, transformation overrides, resource finalization, and persistence behavior;No public API changes are introduced.
from(),factory(),collect(),transform(),all(), andtoArray()retain their signatures and extension boundaries.Performance
Measurements used PHP 8.4.23 on Linux x86-64 with CLI OPcache and JIT disabled. Results are the median across three alternating fresh-process runs against the current
0.4branch. Each standard run used 2,000 operations, seven measured samples, and 100 warm-up operations.0.4p500.4p95AutoLazy, customized collection factories, lazy partials, Eloquent relation loading, and other fallback-heavy scenarios remained within run-to-run noise.
The tradeoffs are deliberately bounded:
The committed benchmark harness reports p50, p95, throughput, query counts, memory, environment details, and checksums. A separate historical comparison fixture remains isolated under
tests/Benchmarks/Dataand is loaded only by its developer benchmark command.Verification
composer fix, including formatting, static analysis, parallel tests, Testbench, and dogfood checks.Summary by CodeRabbit
New Features
Bug Fixes
Documentation