-
Notifications
You must be signed in to change notification settings - Fork 6k
Image.asset will block UI thread when load large image #58572 #18808
Conversation
|
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 on the #hackers channel in Chat. Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
|
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
1 similar comment
|
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
|
@googlebot I signed it! |
|
@liyuqian I had signed CLA, why cla/google always failed? |
|
It's probably because of an email address mismatch. Your commit has an author email of "[email protected]". Can you please double check that's email signed the CLA? If not, you can change your commit email: https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address |
liyuqian
left a comment
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.
It would be nice to add a microbenchmark to test PlatformMessageResponseDart with a 3MB asset. See, e.g., the benchmark in https://github.com/flutter/engine/blob/master/shell/common/shell_benchmarks.cc
| Dart_TypedData_kByteData, heap_data->data(), heap_data->size(), | ||
| heap_data, heap_data->size(), MessageDataFinalizer); | ||
| void* data = malloc(size); | ||
| memset(data, 0, size); |
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.
The memset seems to be unnecessary?
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.
It would be nice to add a microbenchmark to test
PlatformMessageResponseDartwith a 3MB asset. See, e.g., the benchmark in https://github.com/flutter/engine/blob/master/shell/common/shell_benchmarks.cc
PlatformMessageResponseDart only post a ui task, and this ui task will consume time when execute
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.
The
memsetseems to be unnecessary?
Yes, just according to the logical of std::vector
| if (data.size() < kMessageCopyThreshold) { | ||
| Dart_Handle WrapByteData(std::unique_ptr<fml::Mapping> mapping) { | ||
| size_t size = mapping->GetSize(); | ||
| if (size < kMessageCopyThreshold) { |
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 if branch is unnecessary as we're always calling memcpy: whether inside ToByteData, or inside the else branch, or inside the old WrapByteData(std::unique_ptr<fml::Mapping> mapping) function.
| // Avoid copying the contents of messages beyond a certain size. | ||
| const int kMessageCopyThreshold = 1000; | ||
|
|
||
| class DataWrapper { |
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 think this DataWrapper would be unnecessary if we just use ToByteData's implementation inside WrapByteData:
Dart_Handle WrapByteData(std::unique_ptr<fml::Mapping> mapping) {
Dart_Handle data_handle =
Dart_NewTypedData(Dart_TypedData_kByteData, mapping->GetSize());
if (Dart_IsError(data_handle))
return data_handle;
Dart_TypedData_Type type;
void* data = nullptr;
intptr_t num_bytes = 0;
FML_CHECK(!Dart_IsError(
Dart_TypedDataAcquireData(data_handle, &type, &data, &num_bytes)));
memcpy(data, buffer.data(), num_bytes);
Dart_TypedDataReleaseData(data_handle);
return data_handle;
}
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 intend to optimze according to orignal code. The origial code if if (data.size() < kMessageCopyThreshold) , it will use dart vm heap to allocate data, else it use application heap to alloate data, dart vm only use DataWrapper pointer.
If use ToByteData will consume more dart vm heap.
|
The platform message Dart I've created a proposed PR: #18838 The version of Later |
|
ok, but it will use more dart vm heap? |
|
#18838 will allocate small objects on the Dart VM heap and will use a malloc buffer for large objects. This appears to be the best performance tradeoff given how Dart implements |
|
ok, close this PR |
std::vector<uint8_t> data(mapping->GetSize()) consume much time to initialize large arrary