【ios學習】優化 App 的啟動時間實踐 iOS
前言
當用戶按下home鍵的時候,iOS的App並不會馬上被kill掉,還會繼續存活若干時間。理想情況下,使用者點選App的圖示再次回來的時候,App幾乎不需要做什麼,就可以還原到退出前的狀態,繼續為使用者服務。這種持續存活的情況下啟動App,我們稱為熱啟動,相對而言冷啟動就是App被kill掉以後一切從頭開始啟動的過程。我們這裡只討論App冷啟動的情況。
對於冷啟動來說,啟動時間是指從使用者點選 APP 那一刻開始到使用者看到第一個介面這中間的時間。我們進行優化的時候,我們將啟動時間分為 pre-main 時間和 main 函式到第一個介面渲染完成時間這兩個部分。
因為 APP 的入口在 main 函式 ,在 main 函式之後我們的程式碼才會執行。
這裡有兩個階段
1. pre-main階段
1.1. 載入應用的可執行檔案
1.2. 載入動態連結庫載入器dyld(dynamic loader)
1.3. dyld遞迴載入應用所有依賴的dylib(dynamic library 動態連結庫)
2. main()階段
2.1. dyld呼叫main()
2.2. 呼叫UIApplicationMain()
2.3. 呼叫applicationWillFinishLaunching
2.4. 呼叫didFinishLaunchingWithOptions
我們把 pre-main階段稱為 t1,main()階段一直到首個頁面載入完成稱為 t2。
t1 時間的優化分析
t1部分主要參考自APP啟動優化的一次實踐
其中 t1蘋果提供了內建的測量方法, Xcode 中 Edit scheme -> Run -> Auguments 將環境變數 DYLD_PRINT_STATISTICS 設為 1
123456789 | //結果為 Total pre-main time: 1.4 seconds ( 100.0 %) dylib loading time: 1.3 seconds ( 89.4 %) rebase/binding time: 36.75 milliseconds ( 2.5 %) ObjC setup time: 35.65 milliseconds ( 2.4 %) initializer time: 80.97 milliseconds ( 5.5 %) slowest intializers : libSystem.B.dylib : 12.63 milliseconds ( 0.8 %) //解讀 |
1、main()函式之前總共使用了1.4s
2、在94.33ms中,載入動態庫用了1.3s,指標重定位使用了36.75ms,ObjC類初始化使用了35.65ms,各種初始化使用了80.97ms。
3、在初始化耗費的80.97ms中,用時最多的初始化是libSystem.B.dylib。
可以看到,我的 dylib loading time 花費了 1.3s時間,
其中各部分的作用是
載入dylib
分析每個dylib(大部分是iOS系統的),找到其Mach-O檔案,
開啟並讀取驗證有效性,找到程式碼簽名註冊到核心,
最後對dylib的每個segment呼叫mmap()。
rebase/bind
dylib載入完成之後,它們處於相互獨立的狀態,需要繫結起來。
在dylib的載入過程中,系統為了安全考慮,引入了ASLR(Address Space Layout Randomization)技術和程式碼簽名。
由於ASLR的存在,映象(Image,包括可執行檔案、dylib和bundle)會在隨機的地址上載入,和之前指標指向的地址(preferred_address)會有一個偏差(slide),dyld需要修正這個偏差,來指向正確的地址。
Rebase在前,Bind在後,Rebase做的是將映象讀入記憶體,修正映象內部的指標,效能消耗主要在IO。
Bind做的是查詢符號表,設定指向映象外部的指標,效能消耗主要在CPU計算。
OC setup
OC的runtime需要維護一張類名與類的方法列表的全域性表。
dyld做了如下操作:
對所有宣告過的OC類,將其註冊到這個全域性表中(class registration)
將category的方法插入到類的方法列表中(category registration)
檢查每個selector的唯一性(selector uniquing)
如果在各個 OC 類別的 ‘load’方法裡做了不少事情(如在裡面使用 Method swizzle),那麼這是pre-main階段最耗時的部分。dyld執行APP的初始化函式,呼叫每個OC類的+load方法,呼叫C++的構造器函式(attribute((constructor))修飾),建立非基本型別的C++靜態全域性變數,然後執行main函式。
優化思路是
1. 移除不需要用到的動態庫
2. 移除不需要用到的類
3. 合併功能類似的類和擴充套件
4. 儘量避免在+load方法裡執行的操作,可以推遲到+initialize方法中。
t2 時間的優化分析
t2使用了來自NewPan大大 的打點計時器BLStopwatch
檢測耗時
可以看到,我的 APP 載入時間並沒有很慢,但是也想看一看有沒有優化的空間。
在 didFinishLaunchingWithOptions 方法裡我們一般都有以下的邏輯:
初始化第三方 SDK
配置 APP 執行需要的環境
自己的一些工具類的初始化
...
這裡主要參考[iOS]一次立竿見影的啟動時間優化
從優化圖可以看到,我的應用的跳轉邏輯是 開啟 -> 廣告頁 -> 首頁,首頁的UI 架構是:
UITabBarC管理一堆 UINavigationC
但是如果 UI 架構如上,並且在didFinishLaunchingWithOptions裡面設定了根檢視
123456789101112 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSLog(@ "didFinishLaunchingWithOptions 開始執行" ); self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; TestTabBarController *tabBarVc = [TestTabBarController new ]; self.window.rootViewController = tabBarVc; [self.window makeKeyAndVisible]; NSLog(@ "didFinishLaunchingWithOptions 跑完了" ); return YES; } |
然後我們來到 TestTabBarController 裡的 viewDidLoad方法裡進行它的 viewControllers 的設定,然後再進入到每個 viewController 的 viewDidLoad 方法裡進行更多的初始化操作。那麼你覺得從 didFinishLaunchingWithOptions 到最後顯示展示的 viewController 的 viewDidLoad 這些方法的執行順序是怎麼樣的呢?
didFinishLaunchingWithOptions 開始執行
開始載入 TestTabBarController 的 viewDidLoad
didFinishLaunchingWithOptions 跑完了
開始載入 TestViewController 的 viewDidLoad, 然後執行一堆初始化的操作
在TestTabBarController 中操作了 TestViewController 的 view 的話,那麼呼叫順序將會是這樣:
didFinishLaunchingWithOptions 開始執行
開始載入 TestTabBarController 的 viewDidLoad
開始載入 TestViewController 的 viewDidLoad, 然後執行一堆初始化的操作
didFinishLaunchingWithOptions 跑完了
這樣的問題就是當我們把介面的初始化、網路請求、資料解析、檢視渲染等操作放在了viewDidLoad 方法裡,這樣一來每次啟動 APP 的時候,在使用者看到第一個頁面之前,我們要把這些事件全部都處理完,才會進入到檢視渲染階段。
一般來說,我們放到didFinishLaunchingWithOptions執行的程式碼,有很多初始化操作,如日誌,統計,SDK配置等。儘量做到只放必需的,其他的可以延遲到MainViewController展示完成viewDidAppear以後。
* 日誌、統計等必須在 APP 一啟動就最先配置的事件
* 專案配置、環境配置、使用者資訊的初始化 、推送、IM等事件
* 其他 SDK 和配置事件
第一類,必須第一時間啟動,仍然把它留在 didFinishLaunchingWithOptions 裡啟動。
第二類,這些功能在使用者進入 APP 主體的之前是必須要載入完的,我把他放到廣告頁面的viewDidAppear啟動。
第三類,由於啟動時間不是必須的,所以我們可以放在第一個介面的 viewDidAppear 方法裡,這裡完全不會影響到啟動時間。
優化後
這是優化後的啟動時間
優化思路
梳理各個三方庫,找到可以延遲載入的庫,做延遲載入處理,比如放到首頁控制器的viewDidAppear方法裡。
梳理業務邏輯,把可以延遲執行的邏輯,做延遲執行處理。比如檢查新版本、註冊推送通知等邏輯。
避免複雜/多餘的計算。
避免在首頁控制器的viewDidLoad和viewWillAppear做太多事情,這2個方法執行完,首頁控制器才能顯示,部分可以延遲建立的檢視應做延遲建立/懶載入處理。
採用效能更好的API。
首頁控制器用純程式碼方式來構建。
另:[iOS]一次立竿見影的啟動時間優化 提到了使用一個工具類來管理的方法,可以比較方便的管理優化。
總結
前言當用戶按下home鍵的時候,iOS的App並不會馬上被kill掉,還會繼續存活若干時間。理想情況下,使用者點選App的圖示再次回來的時候,App幾乎不需要做什麼,就可以還原到退出前的狀態,繼續為使用者服務。這種持續存活的情況下啟動App,我們稱為熱啟動,相對而言冷啟動就是
iOS app啟動的方式有哪些:
自己啟動(使用者手動點選啟動)urlscheme啟動(關於urlScheme的詳解點選開啟連結)本地通知啟動 (自己寫的本地通知啟動,藍芽模組的啟動,地理圍欄的啟動)遠端通知啟動 (後臺伺服器的推送通知)在appdelegate.m
標籤(空格分隔): 王小草機器學習筆記
筆記整理時間:2016年12月30日
筆記整理者:王小草
1. LDA的實現工具
在主題模型LDA的理論篇,長篇大幅的公式與推導也許實在煩心,也不願意自己去寫程式碼實現一遍的話,不妨用一用一些已經開源和 rms permsize wrapper 2.0 proxy waiting 默認 說明 加載器 Client作為Endpoint的具體實例,下面我們介紹一下Client啟動以及OnStart指令後的額外工作
一、腳本概覽
下面是一個舉例:
/opt comm 配置 err pos service program lba ubun figure 配置 supervisor
[program:HelloWebApp]
command=dotnet run
directory=/home/python/dotnet/myw
前言
\quad\quad
我們都知道,神經網路的學習目的是找到使損失函式的值儘可能小的引數,這是一個尋找最優引數的
1.http://doc.okbase.net/guoyaohua/archive/284335.html
2.https://www.cnblogs.com/guoyaohua/p/8780548.html
原文地址(英文論文):https://www.cnblogs.c
前言
\quad\quad
前面,我們介紹了分類決策樹的實現,以及用 sklearn 庫中的 DecisionTre 今天來整理下netcore在linux(ubuntu)上的執行環境搭建
對應版本
ubuntu 16.04
.net core 2.1
nginx version: nginx/1.10.3 (Ubuntu)
supervisor
Supervisorhttp://super
App啟動模式分類
1.冷啟動
冷啟動狀態:系統不存在該應用的程序。啟動應用才能創建出應用的程序。
一般是中應用在開機後或者系統停止後的第一次啟動過程。因為系統和應用在冷啟動時需要做跟多的工作
所以減少
Objective C 的 Block 是一個很實用的語法,特別是與GCD結合使用,可以很方便地實現併發、非同步任務。但是,如果使用不當,Block
也會引起一些迴圈引用問題(retain
cycle)—— Block 會 retain ‘self’,而 ‘self‘
關於
使用HTML5和CSS來開發手機應用,一直是廣大前端開發者的理想,並且已經有不少解決方案了。例如
PhoneGap(用javascript來呼叫裝置原生API)JQuery Mobile(UI庫)Titanium(混合方式)AppCan(國產的開發工具)
Ioni
機器學習這種計算方式,於上世紀就已經被世人所知,但是受限制於計算機的計算能力和網路速度等原因,沒有得到發展。在摩爾效應下,現在的計算機效能大幅提升,即便是手上的iPhone,都會比當時美國登月所使用的機器要強。於是,在這個背景下,機器學習開始飛速發展,各大公
十、時間的概念
//1.時間本質
Date now=new Date();//獲得當前的CMOS時間
System.out.println(now);
//時間本質上是一個長整數,是1970-1-1(GMT)到現在所經過的毫秒數
System.out.println(now
參考的網上的模板,直接給出程式:
#include "ctime"
#include "time.h"
using namespace std;
string int2string(int value)
{
stringstream ss;
一、前言:大家平時用macbook開發的時候一般都喜歡外接一個顯示器開發吧?這裡我用了一臺2k的顯示器,我們要開啟hidpi模式。你們會問到為什麼要開啟hidpi模式呢?我的2k顯示器是2560*1440分別率,如果採用預設的設定,那麼在顯示器上面的字會特別的小。如果我們開啟
用於評估機器學習模型的就是損失函式,我們訓練的目的基本上都是最小化損失,這個最小化的方式就要用優化演算法了,機器學習中最常用的就是梯度下降演算法。
導數、方向導數和梯度
要了解梯度下降演算法是什麼首要知道梯度是什麼,導數和方向導數又是瞭解梯度的前提。
要解決這個問題其實挺簡單的只需要一個樣式style即可1、在style.xml中新增下面的style 設定啟動圖片<style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
一、實現效果:
通過直接給圖片起預設的名字,讓app啟動頁自動載入啟動圖片。
二、注意點:
·圖片命名一定要按蘋果官方的指定規則命名,圖片的畫素也要符合規則;
·如果橫豎屏圖片都需要,記得在Xcode中勾選上專案支援橫豎屏。
三、官方描述:
1. OC中,與alloc語義相反的方法是dealloc還是release?與retain語義相反的方法是dealloc還是release?為什麼?需要與alloc配對使用的方法是dealloc還是release,為什麼?
以下是針對MRC(手動記憶體釋放)模式:
與all 相關推薦
【ios學習】優化 App 的啟動時間實踐 iOS
【iOS開發】判斷app啟動的方式(launchOptions)
王小草【機器學習】筆記--主題模型LDA實踐與應用
【Spark2.0源碼學習】-6.Client啟動
【.netcore學習】.netcore添加到 supervisor 守護進程自啟動報錯
【深度學習】神經網路的優化方法
【深度學習】深入理解優化器Optimizer演算法(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)
【機器學習】決策樹剪枝優化及視覺化
【netcore基礎】ubuntu 16.04 搭建.net core 2.1 linux 執行環境 nginx反向代理 supervisor配置自啟動 【.NetCore學習】ubuntu16.04 搭建.net core mvc api 執行環境 .Net Core 部署到Ubuntu 16.0
效能優化之App啟動時間
【IOS學習】到底什麼時候才需要在ObjC的Block中使用weakSelf/strongSelf
【Ionic實戰】一個和AngularJS的跨平臺(iOS,Android) APP框架
【機器學習】TensorFlow 在 iOS 端的用例
【java學習】9.時間的概念
【C++學習】之如何用系統日期時間給檔案命名
【iOS學習】Macbook外接2k顯示器開啟hidpi的方法
【機器學習】梯度下降演算法及梯度優化演算法
優化app啟動頁 解決黑屏時間長的問題
【iOS開發】launch Images啟動圖片設定(UILaunchImageFile)之002
【IOS學習】面試iOS工程師的相關問題