8000 [VarExporter] optimize dumped code in time and space by nicolas-grekas · Pull Request #28295 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[VarExporter] optimize dumped code in time and space #28295

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

Merged
merged 1 commit into from
Sep 4, 2018

Conversation

nicolas-grekas
Copy link
Member
@nicolas-grekas nicolas-grekas commented Aug 28, 2018
Q A
Branch? master
Bug fix? no
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR -

Let's squeeze some more µs when running exported code.
On a simple case run 100k times with a few objects, I go from 1.8s to 1.5s.
The generated exports are also a bit smaller if it matters.

This works by:

  • using local variables instead of manually dealing with a stack
  • creating more optimized object hydrators for internal classes

This PR also fixes handling of hard references that are bound to external variables.

};

if ($propertyReflectors) {
self::$configurators[$class] = \Closure::bind(self::$configurators[$class], null, eval('return new class() extends '.$class.'{};'));
Copy link
Member

Choose a reason for hiding this comment

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

It is common for hosts to disable eval for security reasons. Is it possible to keep the less optimized code for such case (checked using function_exists('eval')) ? Or maybe to avoid using eval entirely ?

Copy link
Member Author

Choose a reason for hiding this comment

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

eval is not a function, it's a language construct
how can you disable it?

Copy link
Member

Choose a reason for hiding this comment

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

hmm, indeed, disabling it is not possible through php.ini. It was the suhosin extension disabling it. Not sure how this gets detected then

Copy link
Member Author

Choose a reason for hiding this comment

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

I actually figured out a way to not need eval() and still make the dump more compact are fast.

]),
$r = \Symfony\Component\VarExporter\Internal\Registry::class,
$o = [
clone (($p =& $r::$prototypes)[\DateTime::class] ?? $r::p(\DateTime::class, true)),
Copy link
Member

Choose a reason for hiding this comment

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

why not keeping \Symfony\Component\VarExporter\Internal\Registry::$prototypes ? Is there any benefit to making the class name a variable ?

Copy link
Member Author

Choose a reason for hiding this comment

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

accessing a local var is slightly, and reduces the size of the export as a bonus

Copy link
Member

Choose a reason for hiding this comment

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

I was talking about $r, not about $p

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh sorry. It's purely for compactness, without any performance impact.

Copy link
Member Author

Choose a reason for hiding this comment

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

I removed the$r alias, it's not useful in the end.

@nicolas-grekas nicolas-grekas force-pushed the ve-optim branch 10 times, most recently from 9150a9c to c467ec2 Compare August 31, 2018 14:43
@nicolas-grekas
Copy link
Member Author

comments addressed, thanks @stof
PR ready.

$seen = array();
$prototypesAccess = 0;
$factoriesAccess = 0;
$r = '\\'.Registry::class;
Copy link
Member

Choose a reason for hiding this comment

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

I suggest avoiding the usage of a one-letter variable here to make the code more readable (that code is not generated code).

Or maybe even not using it, as was done before (which would probably even make OPCache resolve some of the concatenations at compile-time)

Copy link
Member Author
@nicolas-grekas nicolas-grekas Sep 1, 2018

Choose a reason for hiding this comment

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

I've been considering this, but honestly, it would make lines longer and less readable to me.
I removed some but I'd prefer leaving the remaining ones as is.

@@ -37,8 +37,6 @@ public function __construct(?Registry $registry, ?Values $values, array $propert

public static function pop($objects, $values, $properties, $value, $wakeups)
Copy link
Member

Choose a reason for hiding this comment

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

should this method still be called pop now ? It is not popping the stack anymore.

Copy link
Member Author

Choose a reason for hiding this comment

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

true, renamed to Hydrator::hydrate()

@nicolas-grekas nicolas-grekas force-pushed the ve-optim branch 3 times, most recently from 8635f03 to 16bbdfc Compare September 1, 2018 13:49
@nicolas-grekas
Copy link
Member Author

I split the Exporter::export() method in 3. Best reviewed ignoring whitespaces now.

@fabpot
Copy link
Member
fabpot commented Sep 4, 2018

Thank you @nicolas-grekas.

@fabpot fabpot merged commit 07e90d7 into symfony:master Sep 4, 2018
fabpot added a commit that referenced this pull request Sep 4, 2018
…colas-grekas)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[VarExporter] optimize dumped code in time and space

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

Let's squeeze some more µs when running exported code.
On a simple case run 100k times with a few objects, I go from 1.8s to 1.5s.
The generated exports are also a bit smaller if it matters.

This works by:
- using local variables instead of manually dealing with a stack
- creating more optimized object hydrators for internal classes

This PR also fixes handling of hard references that are bound to external variables.

Commits
-------

07e90d7 [VarExporter] optimize dumped code in time and space
@nicolas-grekas nicolas-grekas deleted the ve-optim branch September 4, 2018 06:45
@nicolas-grekas nicolas-grekas removed this from the next milestone Nov 1, 2018
@nicolas-grekas nicolas-grekas added this to the 4.2 milestone Nov 1, 2018
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.

4 participants
0