这是indexloc提供的服务,不要输入任何密码
Skip to content

Improve routers performance #42526

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 2 commits into from
Oct 14, 2019
Merged

Conversation

LehaIvanov
Copy link
Contributor

Description

Use the structure LinkedHashMap instead of LinkedHashSet for routes to improve performance. This PR should change complexity for global event dispatching from O((n*(n + 1) / 2) to O(n) .

It seems the subject issue caused by performance regression after these changes because the method Iterable.any is extremely slower than Set.contains ( O(n) vs O(1) )

Related Issues

Tests

I didn't add the tests, because this PR doesn't change the logic and must just improve performance. Please let me know if I should add some performance tests.

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require Flutter developers to manually update their apps to accommodate your change?

  • Yes, this is a breaking change (Please read Handling breaking changes). Replace this with a link to the e-mail where you asked for input on this proposed change.
  • No, this is not a breaking change.

@fluttergithubbot fluttergithubbot added the framework flutter/packages/flutter repository. See also f: labels. label Oct 11, 2019
@fluttergithubbot
Copy link
Contributor

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@googlebot
Copy link

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

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

Looks like a nice optimization. Just some style nits...

@@ -14,8 +14,8 @@ typedef PointerRoute = void Function(PointerEvent event);

/// A routing table for [PointerEvent] events.
class PointerRouter {
final Map<int, LinkedHashSet<_RouteEntry>> _routeMap = <int, LinkedHashSet<_RouteEntry>>{};
final LinkedHashSet<_RouteEntry> _globalRoutes = LinkedHashSet<_RouteEntry>();
final Map<int, LinkedHashMap<PointerRoute, Matrix4>> _routeMap = <int, LinkedHashMap<PointerRoute, Matrix4>>{};
Copy link
Member

Choose a reason for hiding this comment

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

Instead of LinkedHashMap, can you just use Map and when instantiating use the map literal { }? LinkedHashMap is the default implementation that you get there and it reads a lot nicer.

Copy link
Member

Choose a reason for hiding this comment

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

(This applies everywhere in this code)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

PointerEvent event,
LinkedHashMap<PointerRoute, Matrix4> referenceRoutes,
LinkedHashMap<PointerRoute, Matrix4> copiedRoutes,
) => copiedRoutes.forEach((PointerRoute route, Matrix4 transform) {
Copy link
Member

Choose a reason for hiding this comment

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

formatting nit: the ) should be aligned with the void.

Also: Flutter Style only allows the => for functions that fit in one line. This one doesn't, so please change this to use { } style.

Copy link
Contributor Author

@LehaIvanov LehaIvanov Oct 13, 2019

Choose a reason for hiding this comment

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

Fixed. I've also broken some lines for fitting them in 80 chars in this commit. Is this OK? Or is it better to revert these changes?

PointerEvent event,
LinkedHashMap<PointerRoute, Matrix4> referenceRoutes,
LinkedHashMap<PointerRoute, Matrix4> copiedRoutes,
) => copiedRoutes.forEach((PointerRoute route, Matrix4 transform) {
Copy link
Member

Choose a reason for hiding this comment

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

If you're concerned about performance in this code path: It may be faster to use a regular for loop over the keys then calling forEach. If you have a benchmark for this, you may want to try that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After reading this commit I thought that 'for-in' loop could be really faster, however, I decided to create benchmark tests for checking this supposition. And tests show that 'forEach' is faster than 'for-in'.

You can view these benchmark tests in the repository, two code blocks are compared there. These ones:

map.forEach((String key, int value) {
    ...
});

and

for (String key in map.keys) {
    ...
}

@LehaIvanov LehaIvanov requested a review from goderbauer October 13, 2019 12:23
Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

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

LGTM

@LehaIvanov LehaIvanov changed the title Issues/42518 Improve routers performance Oct 14, 2019
Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

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

LGTM

@goderbauer goderbauer merged commit 8cc9a53 into flutter:master Oct 14, 2019
@LehaIvanov LehaIvanov deleted the issues/42518 branch October 18, 2019 06:24
Inconnu08 pushed a commit to Inconnu08/flutter that referenced this pull request Nov 26, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Scrolling performance problem when using many tooltips
5 participants