写点什么

Flutter 性能优化之 Isolates

用户头像
Daniel
关注
发布于: 2020 年 09 月 19 日

原文(英文):https://medium.com/flutterdevs/flutter-performance-optimization-17c99bb31553  



曾经想知道flutter如何在单个线程上处理所有UI构建和事件,例如Future,taps等。(是的,它在单个线程上完成所有操作😮😮😮直到明确完成)。



什么是Thread/Isolates?



线程是一个独立的处理过程,具有自己的内存块并在该内存上执行给定的指令。它可以与其他线程并行工作,因此可以减少单个CPU上多个进程的执行时间。



让我们通过一个例子来理解这一点:



在Fps游戏中,例如反恐精英,使命召唤等,您可以看到,一旦发射武器,便同时执行了几项任务,例如播放子弹声,改变子弹数和减少对手的生命值,这些并行执行并在单独的隔离上(Thread/Isolates可以互换使用),它具有自己的内存。



诸如JAVA和C ++线程共享它们的内存。flutter每个Isolates都有自己的内存,是相互独立的。由于该内存具有自己的私有空间,因此不需要锁定,用完了就可以垃圾回收。



为了保持这些好处,flutter每个Isolates(Flutter的多线程)都有一个单独的内存,这就是为什么它们被称为isolate🙂。



在下面了解有关Isolates的更多信息。



它对我有什么帮助?在哪里应该使用Isolates/threads?

1 网络请求,要处理大约一百万条记录,仅此一项就会挂起您的UI。



2 图像处理任务,需要大量的计算,数字运算操作,这可能会导致UI卡死。



因此,Isolates可以从主线程中卸载出来大量计算。



如何使用Isolates/threads

Flutter团队设计了一种在flutter中使用Isolates/threads方法。使用compute,我们可以执行与isolates相同的任务



句法:



var getData = await compute(function,parameter);



compute两个参数:



1 future或function,但必须是静态的(如dart线程不共享内存,因此它们是类成员,而不是对象成员)。



2 要传递给function的参数,要发送多个参数,可以将其作为Map传递(因为它仅支持单个参数)。



计算函数返回一个Future,如果需要,可以将其存储到变量中并将其提供给future构建器。



让我们开始分析一个案例:



import 'dart:io';

import 'package:flutter/material.dart';

class With10SecondDelay extends StatelessWidget {
runningFunction() {
int sum = 0;
for (int i = 1; i <= 10; i++) {
sleep(Duration(seconds: 1));
print(i);
sum += i;
}
return "total sum is $sum";
}

pauseFunction() {
//pause function is not async
print(runningFunction());
}

@override
Widget build(BuildContext context) {
pauseFunction();
return Material(
child: Center(
child: Center(
child: Text(
"Tnx for waiting 10 seconds : check console for response",
style: TextStyle(
fontSize: 50,
),
),
),
),
);
}
}



在上面的代码中,在build方法正下方调用了pausefunction(),该方法将代码的执行暂停10秒钟。因此,当您尝试从上一个页面导航到该页面时,将有十秒钟的延迟,然后我们的页面被推到小部件树上。



我们可以尝试使用异步解决此问题。

pauseFunction() async {
//pause function is async
print(runningFunction());
}



如您现在所见,我们已经将暂停功能声明为异步,即使这样做也无济于事



由于dart中的async基本上使我们的代码处于理想状态,直到可以进行计算为止,因此在我们看来dart在不同的线程上执行这些操作,但实际上它只是在等待该async函数中发生的事件。



以下是有关异步的更多信息:https://youtu.be/SmTCmDMi4BY :)



让我们使用compute解决上述问题。


import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class ComputeWith10SecondDelay extends StatelessWidget {
static Future<String> runningFunction(String str) async {
int sum = 0;
for (int i = 1; i <= 10; i++) {
await Future.delayed(Duration(seconds: 1));
print(i);
sum += i;
}
return "Sum is : " + sum.toString() + str;
}

pauseFunction() async {
print(await compute(runningFunction,
" This is an argument")); //storing data of copute result
}

@override
Widget build(BuildContext context) {
pauseFunction();

return Material(
child: Center(
child: Center(
child: Text(
"Wow , it saved my 10 seconds : check console for response",
style: TextStyle(
fontSize: 50,
),
),
),
),
);
}
}



在上面的代码中,我们基本上将函数传递给了compute()函数,并创建了一个单独的隔离来处理任务,我们的主UI仍将无任何延迟地运行(请检查调试控制台以获取响应)。



摘要:



1 默认情况下,Dart是在单线程上执行其所有代码。



2 每个函数和每个async-await调用仅在主线程上起作用(除非指定)。



3 我们可以使用compute(Future function / normal function,arguments)创建多个线程。



4 您可以使用计算来执行网络呼叫,执行数字运算,图像处理等。



-------------------------------------------------------------------------



如有版权问题,请联系本人 qq: 120022950



发布于: 2020 年 09 月 19 日阅读数: 774
用户头像

Daniel

关注

还未添加个人签名 2019.02.27 加入

还未添加个人简介

评论

发布
暂无评论
Flutter 性能优化之Isolates