Repository navigation
Read built in decoder properties from ElementLookup directly - #84
Merged
Merged
Conversation
Hoist per property type meta out of the object loops
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
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 |
Xmlns::xsi() builds a new object on every call. OptionalElementEncoder now resolves it once per iso, and DocumentToLookupArrayReader compares against a class constant.
Locator\Node\value() reads substitutedNodeValue and coerces it to a string, which it already is on a Dom\Element. Reading the property skips the function call and the Psl coercion.
…per-decode-reads # Conflicts: # src/Xml/Reader/DocumentToLookupArrayReader.php
veewee
added this pull request to stack #88
October 16, 2026 07:33
Every property of a decoded object went through Lens::readonly, its closure and the try/catch in runLens, only to call element(), attribute() or text() on the lookup. ObjectAccess now records per property how the built in lens reads it, and ObjectEncoder::from makes that call itself. Those three calls cannot throw, so the try/catch had nothing to catch for them. Custom ProvidesObjectDecoderLens lenses keep going through runLens. The built in lenses stay in decoderLenses and are built from the same record, so they read exactly what the direct call reads.
… too Missing elements, attributes in another namespace and nil or mixed text all read null, and those are the reads where a lens and the direct call could differ.
veewee
force-pushed
the
perf-direct-element-lookup
branch
from
October 16, 2026 07:34
d5ceee2 to
a9cc817
Compare
Cheaper xsi:nil checks and value reads on decode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #80, so it targets that branch until it is merged.
Lens overhead on decode
#80 moved decoding to
ElementLookup, and that made sparse decoding a little slower than on #79. When I profiled it, nearly all of the difference came from the lens indirection. Every property went throughLens::readonly, its closure and the try/catch inrunLens, only to callelement(),attribute()ortext()on the lookup.One plain reader per property
ObjectAccessnow keeps one closure per property for each direction,decodeReadersandencodeReaders. A built in decode reader calls the lookup directly, and the encode reader is reflecta's throwlessoptional_property. A customProvidesObjectDecoderLensorProvidesObjectEncoderLenslens is called as is, sorunLens, the try/catch and theoptional()wrap are gone.Custom lenses that throw
A custom lens used to have its exception swallowed and read as null. Now the exception fails the encode or decode as an
EncodingException, with the original exception as previous. Custom object lenses must handle their own misses, for example withoptional()oroptional_property(). A null from a custom lens still never counts as absent (#79).Same output
The decoded results and encoded requests of the 3MB workloads have the same sha1 as #80.
Speed
Base is
element-lookup(#80). Medians over three interleaved rounds on the same machine.Encode and the phpbench subjects stay within the run to run spread. An earlier version of this PR read the lookup inline through a
matchand reached -13% on sparse stdClass. I dropped that for one shape per property and less code.