-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
Replace module dependency sort algorithm #11164
Replace module dependency sort algorithm #11164
Conversation
For the reference: previous attempt to improve this sorting was performed in #10649 Did you do some benchmarking? Amount of |
@orlangur Yes, you are right. I run "bin/magento" with blackfire. Blackfire shows a ~20% better performance overall. |
And, before discussing a concrete implementation in details, what do you think about using an existing #10649 (comment) topological sorting implementation? My main concern regarding current implementation is that it encapsulates pretty abstract algorithm in concrete application. While it would be nice to have some universal |
OK. We can move the algorithm in a new class where we can add elements. Every element should have an "id" attribute which must be unique. Every element can have a "payload" which can have type "mixed". So we can reuse the logic in other parts of the system. |
Thanks for quick feedback!
Could you please evaluate this suggestion? In such case new Magento class will just prepare list of modules in correct format. |
I tested this yesterday with Anton during the Magento Hackathon Munich. |
Ok, thanks. We can have "own" implementation by wrapping a good one in some Magento Framework component by the way :) |
*/ | ||
public function __construct( | ||
Dom $converter, | ||
Parser $parser, | ||
ComponentRegistrarInterface $moduleRegistry, | ||
DriverInterface $filesystemDriver | ||
DriverInterface $filesystemDriver, | ||
Sorter $sorter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case I think the Sorter
parameter should be optional http://devdocs.magento.com/guides/v2.2/contributor-guide/backward-compatible-development/#adding-a-constructor-parameter
* @param array $parentElements | ||
* @throws \Exception | ||
*/ | ||
protected function processElement($element, $parentElements = []) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be updated to private since I think it is only used inside this class?
@@ -0,0 +1,83 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 1999-2017 netz98 GmbH (http://www.netz98.de) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is a php storm autocomplete. I guess this should be the Magento docblock instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:-) Yes, you catched me. I will change the PhpStorm template.
@orlangur Yes, that is the plan. Anton is not to be a fan of too many 3rd party integrations. |
Ok, and I'm not a big fan of reinventing the wheels when we can easily wrap and reuse something :) As this logic is just a part of CLI and I'm not sure it is covered by any performance test, could you do a little benchmark? No need in performance boost, just to make sure there is no accidental degradation.
I believe you already did some counting, just do timer start in the beginning and timer stop in the very end. Will do a full review soon. |
@@ -97,7 +105,7 @@ public function load(array $exclude = []) | |||
$result[$name] = $data[$name]; | |||
} | |||
} | |||
return $this->sortBySequence($result); | |||
return $this->sorter->sort($result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like SequenceSorter
seems to be a more appropriate name (both class and injected argument).
/** | ||
* @var array | ||
*/ | ||
private $origList; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
orig -> original
* @param array $origList | ||
* @return array | ||
*/ | ||
public function sort(array $origList) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please specify in PHPDoc of this method exact algorithm used.
protected function processElement($element, $parentElements = []) | ||
{ | ||
if (isset($parentElements[$element['name']])) { | ||
$relatedName = implode('', array_slice(array_keys($parentElements), -1, 1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is quite ineffective operation. Looks like you needed https://stackoverflow.com/a/2348213/8640867
@@ -54,7 +55,9 @@ protected function setUp() | |||
$this->parser->expects($this->once())->method('initErrorHandler'); | |||
$this->registry = $this->createMock(\Magento\Framework\Component\ComponentRegistrarInterface::class); | |||
$this->driver = $this->createMock(\Magento\Framework\Filesystem\DriverInterface::class); | |||
$this->loader = new Loader($this->converter, $this->parser, $this->registry, $this->driver); | |||
|
|||
$sorter = new Sorter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot test two classes in unit test. Create a new test specifically for SequenceSorter
and remove anything unrelated from this one.
UPD: great, you already created such test 👍 Just mock SequenceSorter
here then.
use Magento\Framework\Module\ModuleList\Sorter; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class SorterTest extends TestCase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make sure new class is 100% covered. At least there is no test for Circular sequence reference from
exception currently.
The new algorithm replace the old bubble sort with a new topological sort. This eliminates 53.000 is_array and 35.000 array_unique calls.
Hi @cmuench, any updates on this one? |
Closing due to inactivity. Feel free to reach me out anytime later if you wish to continue work on pull request and it will be reopened. |
The new algorithm replaces the old bubble sort with a new topological
sort. This eliminates 53.000 is_array and 35.000 array_unique calls.
Description
The sort logic is moved into a new Sorter class. In the main class a bunch of code
could be removed. The new logic is much more simple than the old one.
Manual testing scenarios
Add a new module dependency.
Circular reference check can be tested by adding a circular reference in modules.xml files.
Contribution checklist