Flutter 性能優化之Isolates

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文(英文):"},{"type":"link","attrs":{"href":"https://medium.com/flutterdevs/flutter-performance-optimization-17c99bb31553","title":null},"content":[{"type":"text","text":"https://medium.com/flutterdevs/flutter-performance-optimization-17c99bb31553"}]},{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"曾經想知道flutter如何在單個線程上處理所有UI構建和事件,例如Future,taps等。(是的,它在單個線程上完成所有操作😮😮😮直到明確完成)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"什麼是Thread/Isolates?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"線程是一個獨立的處理過程,具有自己的內存塊並在該內存上執行給定的指令。它可以與其他線程並行工作,因此可以減少單個CPU上多個進程的執行時間。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"讓我們通過一個例子來理解這一點:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在Fps遊戲中,例如反恐精英,使命召喚等,您可以看到,一旦發射武器,便同時執行了幾項任務,例如播放子彈聲,改變子彈數和減少對手的生命值,這些並行執行並在單獨的隔離上(Thread/Isolates可以互換使用),它具有自己的內存。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"諸如JAVA和C ++線程共享它們的"},{"type":"link","attrs":{"href":"https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/garbage_collect.html","title":null},"content":[{"type":"text","text":"堆"}]},{"type":"text","text":"內存。flutter每個Isolates都有自己的內存,是相互獨立的。由於該內存具有自己的私有空間,因此不需要鎖定,用完了就可以垃圾回收。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了保持這些好處,flutter每個Isolates(Flutter的多線程)都有一個單獨的內存,這就是爲什麼它們被稱爲"},{"type":"text","marks":[{"type":"strong"}],"text":"isolate🙂。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"在下面瞭解有關Isolates的更多信息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"它對我有什麼幫助?在哪裏應該使用Isolates/threads?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1 網絡請求,要處理大約一百萬條記錄,僅此一項就會掛起您的UI。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2 圖像處理任務,需要大量的計算,數字運算操作,這可能會導致UI卡死。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,Isolates可以從主線程中卸載出來大量計算。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"如何使用Isolates/threads"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Flutter團隊設計了一種在flutter中使用Isolates/threads方法。使用"},{"type":"text","marks":[{"type":"strong"}],"text":"compute"},{"type":"text","text":",我們可以執行與isolates相同的任務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"句法:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"var getData = await compute(function,parameter);"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"compute"},{"type":"text","text":"兩個參數:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1 future或function,但必須是靜態的(如dart線程不共享內存,因此它們是類成員,而不是對象成員)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2 要傳遞給function的參數,要發送多個參數,可以將其作爲Map傳遞(因爲它僅支持單個參數)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"計算函數返回一個Future,如果需要,可以將其存儲到變量中並將其提供給future構建器。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"讓我們開始分析一個案例:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"import 'dart:io';\n\nimport 'package:flutter/material.dart';\n\nclass With10SecondDelay extends StatelessWidget {\n runningFunction() {\n int sum = 0;\n for (int i = 1; i <= 10; i++) {\n sleep(Duration(seconds: 1));\n print(i);\n sum += i;\n }\n return \"total sum is $sum\";\n }\n\n pauseFunction() {\n //pause function is not async\n print(runningFunction());\n }\n\n @override\n Widget build(BuildContext context) {\n pauseFunction();\n return Material(\n child: Center(\n child: Center(\n child: Text(\n \"Tnx for waiting 10 seconds : check console for response\",\n style: TextStyle(\n fontSize: 50,\n ),\n ),\n ),\n ),\n );\n }\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在上面的代碼中,在build方法正下方調用了pausefunction(),該方法將代碼的執行暫停10秒鐘。因此,當您嘗試從上一個頁面導航到該頁面時,將有十秒鐘的延遲,然後我們的頁面被推到小部件樹上。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們可以嘗試使用異步解決此問題。"}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":" pauseFunction() async {\n //pause function is async\n print(runningFunction());\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如您現在所見,我們已經將暫停功能聲明爲異步,即使這樣做也無濟於事"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於dart中的async基本上使我們的代碼處於理想狀態,直到可以進行計算爲止,因此在我們看來dart在不同的線程上執行這些操作,但實際上它只是在等待該async函數中發生的事件。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"以下是有關異步的更多信息:"},{"type":"link","attrs":{"href":"https://youtu.be/SmTCmDMi4BY","title":null},"content":[{"type":"text","text":""}]},{"type":"link","attrs":{"href":"https://youtu.be/SmTCmDMi4BY","title":null},"content":[{"type":"text","text":"https://youtu.be/SmTCmDMi4BY"}]},{"type":"text","text":" :)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"讓我們使用compute解決上述問題。"}]},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\nimport 'dart:io';\n\nimport 'package:flutter/foundation.dart';\nimport 'package:flutter/material.dart';\n\nclass ComputeWith10SecondDelay extends StatelessWidget {\n static Future runningFunction(String str) async {\n int sum = 0;\n for (int i = 1; i <= 10; i++) {\n await Future.delayed(Duration(seconds: 1));\n print(i);\n sum += i;\n }\n return \"Sum is : \" + sum.toString() + str;\n }\n\n pauseFunction() async {\n print(await compute(runningFunction,\n \" This is an argument\")); //storing data of copute result\n }\n\n @override\n Widget build(BuildContext context) {\n pauseFunction();\n\n return Material(\n child: Center(\n child: Center(\n child: Text(\n \"Wow , it saved my 10 seconds : check console for response\",\n style: TextStyle(\n fontSize: 50,\n ),\n ),\n ),\n ),\n );\n }\n}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在上面的代碼中,我們基本上將函數傳遞給了compute()函數,並創建了一個單獨的隔離來處理任務,我們的主UI仍將無任何延遲地運行(請檢查調試控制檯以獲取響應)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"摘要:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1 默認情況下,Dart是在單線程上執行其所有代碼。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2 每個函數和每個async-await調用僅在主線程上起作用(除非指定)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3 我們可以使用compute(Future function / normal function,arguments)創建多個線程。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4 您可以使用計算來執行網絡呼叫,執行數字運算,圖像處理等。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-------------------------------------------------------------------------"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如有版權問題,請聯繫本人 qq: 120022950"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章