Performance fix for Guid initializers #552
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR aims at fixing a performance pitfall in the current implementation of Guid initializers.
Both
Guid(String input)
andGuid.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: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.
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:
As you can see, cpu time is now better distributed across framework tasks and the disproportion of
Guid
methods is no longer perceivable.