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

Performance fix for Guid initializers #552

Merged
merged 3 commits into from
Apr 18, 2020

Conversation

ezamagni
Copy link
Contributor

This PR aims at fixing a performance pitfall in the current implementation of Guid initializers.
Both Guid(String input) and Guid.fromMac(String input) perform a test on the input String through _fromString and _fromMacString methods respectively. The test is operated using a regular expression to catch the expected number of hex couples and decode them to a list of bytes:

final RegExp regex = new RegExp('[0-9a-f]{2}');

The problem with this approach is the performance cost of performing a Regex every time a Guid is created either by a client application (which might be negligible) or by flutter_blue itself (which hits the Guid initializer a lot of times).
Even if Dart is not particularly slow on regex, flutter_blue uses the Guid initializers very frequently, especially in those scenarios when a BT characteristic is read/written/indicated at short intervals.

To verify this behavior I profiled a small application that reads from a characteristic about 2 times in a second.
Schermata 2020-04-18 alle 10 52 58
As you can see from the above flame chart, a lot of time is spent in Guid._fromString method.

In this PR i modified both _fromString and _fromMacString methods not to use any regex check but instead simply decode the input string to hex bytes after all non-hex characters are stripped from it.
The procedure to remove non-hex character has also been improved to run in a single pass, instead of three consecutive .replaceAll calls.
All the preexisting checks regarding the expected length of bytes are still left intact, all the tests in guid_tests.dart are passing.

Profiling the same application after the optimizations yields the following flame chart:
Schermata 2020-04-18 alle 11 26 05

As you can see, cpu time is now better distributed across framework tasks and the disproportion of Guid methods is no longer perceivable.

Copy link
Owner

@pauldemarco pauldemarco left a comment

Choose a reason for hiding this comment

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

Nicely done!

@pauldemarco
Copy link
Owner

LGTM

@pauldemarco pauldemarco reopened this Apr 18, 2020
@pauldemarco pauldemarco merged commit 47067e4 into pauldemarco:master Apr 18, 2020
@ezamagni ezamagni deleted the performance-guid branch November 18, 2021 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants