Skip to content

[Routing] Fix same-prefix aggregation #26208

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
Feb 19, 2018

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented Feb 17, 2018

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

Follows #26059 and #26169.

The blog post on http://symfony.com/blog/new-in-symfony-4-1-fastest-php-router made me review the aggregation logic, and discover issues.

So now, instead of this:

        .'|/(en|fr)/admin/post/?(*:82)'
        .'|/(en|fr)/admin/post/new(*:166)'
        .'|/(en|fr)/admin/post/(\\d+)(*:253)'
        .'|/(en|fr)/admin/post/(\\d+)/edit(*:345)'
        .'|/(en|fr)/admin/post/(\\d+)/delete(*:442)'
        .'|/(en|fr)/blog/?(*:519)'
        .'|/(en|fr)/blog/rss\\.xml(*:603)'
        .'|/(en|fr)/blog/page/([^/]++)(*:694)'
        .'|/(en|fr)/blog/posts/([^/]++)(*:784)'
        .'|/(en|fr)/blog/comment/(\d+)/new(*:880)'
        .'|/(en|fr)/blog/search(*:962)'
        .'|/(en|fr)/login(*:1038)'
        .'|/(en|fr)/logout(*:1116)'
        .'|/(en|fr)?(*:1188)'

we generate this:

        .'|/(en|fr)(?'
            .'|/admin/post(?'
                .'|/?(*:34)'
                .'|/new(*:45)'
                .'|/(\\d+)(?'
                    .'|(*:61)'
                    .'|/edit(*:73)'
                    .'|/delete(*:87)'
                .')'
            .')'
            .'|/blog(?'
                .'|/?(*:106)'
                .'|/rss\\.xml(*:123)'
                .'|/p(?'
                    .'|age/([^/]++)(*:148)'
                    .'|osts/([^/]++)(*:169)'
                .')'
                .'|/comments/(\\d+)/new(*:197)'
                .'|/search(*:212)'
            .')'
            .'|/log(?'
                .'|in(*:230)'
                .'|out(*:241)'
            .')'
        .')'
        .'|/(en|fr)?(*:260)' 

This is not only another perf fix, but a real bug fix, as I found ordering issues.

return null;
list($commonPrefix, $commonStaticPrefix) = $this->getCommonPrefix($prefix, $this->prefixes[$i]);

if (strlen($this->prefix) >= strlen($commonPrefix)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure how often this is called or if performance matters, but the prefix property doesn't change from what I can tell, should the result be cached? There are a few there are a few more uses of this property like this.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed by adding a \, nothing else to gain from caching the length

}

/**
* Checks whether a prefix can be contained within the group.
*/
private function accepts(string $prefix): bool
{
return '' === $this->prefix || 0 === strpos($prefix, $this->prefix);
return 0 === strpos($prefix, $this->prefix) && '?' !== ($prefix[\strlen($this->prefix)] ?? '');
Copy link
Contributor

Choose a reason for hiding this comment

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

Isnt the 2nd check faster then the first ..? Should order of the check be in reverse order?

Copy link
Member Author

@nicolas-grekas nicolas-grekas Feb 18, 2018

Choose a reason for hiding this comment

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

the 2nd check is also always true, the 1st less. I'd keep it this way, feels more readable IMHO

@fabpot
Copy link
Member

fabpot commented Feb 19, 2018

Thank you @nicolas-grekas.

@fabpot fabpot merged commit d514f81 into symfony:master Feb 19, 2018
fabpot added a commit that referenced this pull request Feb 19, 2018
This PR was merged into the 4.1-dev branch.

Discussion
----------

[Routing] Fix same-prefix aggregation

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

The blog post on http://symfony.com/blog/new-in-symfony-4-1-fastest-php-router made me review the aggregation logic, and discover issues.

So now, instead of this:
```
        .'|/(en|fr)/admin/post/?(*:82)'
        .'|/(en|fr)/admin/post/new(*:166)'
        .'|/(en|fr)/admin/post/(\\d+)(*:253)'
        .'|/(en|fr)/admin/post/(\\d+)/edit(*:345)'
        .'|/(en|fr)/admin/post/(\\d+)/delete(*:442)'
        .'|/(en|fr)/blog/?(*:519)'
        .'|/(en|fr)/blog/rss\\.xml(*:603)'
        .'|/(en|fr)/blog/page/([^/]++)(*:694)'
        .'|/(en|fr)/blog/posts/([^/]++)(*:784)'
        .'|/(en|fr)/blog/comment/(\d+)/new(*:880)'
        .'|/(en|fr)/blog/search(*:962)'
        .'|/(en|fr)/login(*:1038)'
        .'|/(en|fr)/logout(*:1116)'
        .'|/(en|fr)?(*:1188)'
```

we generate this:
```
        .'|/(en|fr)(?'
            .'|/admin/post(?'
                .'|/?(*:34)'
                .'|/new(*:45)'
                .'|/(\\d+)(?'
                    .'|(*:61)'
                    .'|/edit(*:73)'
                    .'|/delete(*:87)'
                .')'
            .')'
            .'|/blog(?'
                .'|/?(*:106)'
                .'|/rss\\.xml(*:123)'
                .'|/p(?'
                    .'|age/([^/]++)(*:148)'
                    .'|osts/([^/]++)(*:169)'
                .')'
                .'|/comments/(\\d+)/new(*:197)'
                .'|/search(*:212)'
            .')'
            .'|/log(?'
                .'|in(*:230)'
                .'|out(*:241)'
            .')'
        .')'
        .'|/(en|fr)?(*:260)'
```

This is not only another perf fix, but a real bug fix, as I found ordering issues.

Commits
-------

d514f81 [Routing] Fix same-prefix aggregation
@nicolas-grekas nicolas-grekas deleted the routing-fix branch February 19, 2018 10:35
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.

6 participants