Heya,

Reflection is not slow: it is only slow if you instantiate it continuously.

On Wed, 6 Feb 2019, 12:38 Benjamin Morel <benjamin.mo...@gmail.com wrote:

> Hi Nikita,
>
> While playing with typed properties, something that annoys me a lot, in the
> context of a data mapper, is not to be able to use isset() to check whether
> an object's property is initialized. The issue was already there with
> properties that have been explicitly unset(), but will be exacerbated by
> typed properties, which will be unset *by default*.
>
> Sure, we have ReflectionProperty::isInitialized(), but reflection is slow
> compared to direct property access, when reading a lot of objects.
>
> For example, check these 3 ways of reading initialized public/protected
> object properties by name, along with their timings for 100,000 iterations
> (benchmark here
> <
> https://gist.github.com/BenMorel/9a920538862e4df0d7041f8812f069e5#file-reflection-vs-array-cast-benchmark-php
> >
> ):
>
> Using reflection: (890 ms, down to 384 ms using pre-instantiated
> ReflectionProperty objects)
>
>     $r = new \ReflectionClass($class);
> >     foreach ($props as $prop) {
> >         $p = $r->getProperty($prop);
> >         $p->setAccessible(true);
> >         if ($p->isInitialized($object)) {
> >             $values[$p->getName()] = $p->getValue($object);
> >         }
> >     }
>
>
> Using array cast: (193 ms)
>
>     foreach ((array) $object as $key => $value) {
> >         // Remove the "\0*\0" in front of protected properties
> >         $pos = strrpos($key, "\0");
> >         if ($pos !== false) {
> >             $key = substr($key, $pos + 1);
> >         }
> >         $values[$key] = $value;
> >     }
>
>
> Using a bound closure and isset(): (145 ms)
>
>
> >     (function() use ($props, & $values) {
> >         foreach ($props as $prop) {
> >             if (isset($this->{$prop})) { // skips NULL values as well :-(
> >                 $values[$prop] = $this->{$prop};
> >             }
> >         }
> >     })->bindTo($object, $object)();
>
>
> Unfortunately, while the last approach is the fastest, and IMO the cleanest
> one, it is currently unusable because there is no way to differentiate
> between an uninitialized property and a NULL property.
>
> Would it be possible to introduce another isset() operator, that would
> return true for NULL values?
> Note that this would also be useful when checking if an array key exists,
> instead of having to switch from isset() to array_key_exists() when the
> array may contain NULL values.
>
> Ben
>
> On Fri, 11 Jan 2019 at 17:38, Nikita Popov <nikita....@gmail.com> wrote:
>
> > On Mon, Oct 22, 2018 at 1:58 PM Sebastian Bergmann <sebast...@php.net>
> > wrote:
> >
> > > Am 26.09.2018 um 15:46 schrieb Nikita Popov:
> > > > I'm pleased to announce that the typed properties RFC has been
> accepted
> > > > with 70 votes in favor and one vote against. We will work to finalize
> > and
> > > > merge the implementation in the next few days.
> > >
> > > Any update on when this will be merged? Thanks!
> > >
> >
> > Sorry for the long delay here. I've spent the last week fixing the
> > remaining issues and cleaning up the patch, and...
> >
> > ...Typed properties are now merged into master! [1]
> >
> > It would be great if people could start experimenting with typed
> properties
> > (e.g. by migrating over existing @var annotations and seeing what
> happens).
> > The earlier we find issues in the implementation or semantics, the
> better.
> >
> > Thanks to everyone who worked on this RFC and participated in
> discussions.
> > Special thanks to Bob Weinand who did most of the initial implementation
> > work on this RFC.
> >
> > Regards,
> > Nikita
> >
> > [1]:
> >
> >
> https://github.com/php/php-src/commit/e219ec144ef6682b71e135fd18654ee1bb4676b4
> >
>

Reply via email to