Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not use property metadata to get/set object values #934

Merged
merged 3 commits into from
May 2, 2018

Conversation

goetas
Copy link
Collaborator

@goetas goetas commented May 2, 2018

Q A
Bug fix? no
New feature? no
Doc updated no
BC breaks? yes
Deprecations? no
Tests pass? yes
Fixed tickets #932
License Apache-2.0

first draft of what could be a solution for #932. To get some extra memory improvements, even jms/metadata should be updated (removing the reflection stuff from property metadata)

@goetas goetas added this to the v2.0 milestone May 2, 2018

public function getValue(object $object, PropertyMetadata $metadata)
{
return $metadata->getValue($object);
if ($metadata instanceof StaticPropertyMetadata) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. This bunch of IFs calls for a strategy pattern imho, this is a bit too coupled.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this has to be fast! very fast! 🤔
not sure if having extra classes to load and call will influence on it


/**
* @author Asmir Mustafic <[email protected]>
*/
final class DefaultAccessorStrategy implements AccessorStrategyInterface
{
private $readAccessors = array();
private $writeAccessors = array();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inho one shared accessor is enough, no? They are bound to type only.

Copy link
Collaborator Author

@goetas goetas May 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The body of the closure is different,

function ($o, $name, $value) {
   $o->$name = $value;
}

vs

function ($o, $name) {
   return $o->$name;
}

so cant be done

@Majkl578
Copy link
Contributor

Majkl578 commented May 2, 2018

As an experiment (perf), you could also try closures bound to specific object instances and/or properties.

@goetas
Copy link
Collaborator Author

goetas commented May 2, 2018

As an experiment (perf), you could also try closures bound to specific object instances and/or properties.

Can you explain?

@Majkl578
Copy link
Contributor

Majkl578 commented May 2, 2018

Right now you are using unbound accessors (2nd argument to Closure::bind() is null) so you have to pass around $o as an object instance.
If you bind the closure to specific object, you can simply use $this->$propertyName instead.

@Majkl578
Copy link
Contributor

Majkl578 commented May 2, 2018

Btw this needs some test cases for inheritance with private properties: with different names, with same names (but different serialized names) and so.

@goetas
Copy link
Collaborator Author

goetas commented May 2, 2018

Right now you are using unbound accessors (2nd argument to Closure::bind() is null) so you have to pass around $o as an object instance.
If you bind the closure to specific object, you can simply use $this->$propertyName instead.

But if i do it per object is much slower... creating the closure takes a lot apparently.

@goetas
Copy link
Collaborator Author

goetas commented May 2, 2018

Btw this needs some test cases for inheritance with private properties: with different names, with same names (but different serialized names) and so.

The whole testsuite is using this access strategy, so should work, no?

@Majkl578
Copy link
Contributor

Majkl578 commented May 2, 2018

Not sure. Your accessor is bound to specific class name which is crucial for private properties.
Assume this code:

class Foo
{
    /** @Serializer\SerializedName("foo") */
    private $a;
}

class Bar extends Foo
{
    /** @Serializer\SerializedName("bar") */
    private $a;
}

Will that work when $o instanceof Bar? (Or actually does that work now? 😆 )

@goetas
Copy link
Collaborator Author

goetas commented May 2, 2018

#935 proves that does not work :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants