OC底層知識(shí)(六) : 性能優(yōu)化

一抑进、CPU和GPU 的介紹

  • 1.1秃症、在屏幕成像的過程中,CPU和GPU起著至關(guān)重要的 作用
    • CPU(Central Processing Unit慢叨,中央處理器),對(duì)象的創(chuàng)建和銷毀务蝠、對(duì)象屬性的調(diào)整拍谐、布局計(jì)算、文本的計(jì)算和排版请梢、圖片的格式轉(zhuǎn)換和解碼赠尾、圖像的繪制(Core Graphics)
    • GPU(Graphics Processing Unit,圖形處理器)毅弧,紋理的渲染,說白了就是界面的展示


      CPU和GPU的機(jī)制圖
    • 在iOS中是雙緩沖機(jī)制当窗,有前幀緩存够坐、后幀緩存
  • 1.2、屏幕成像原理


    屏幕成像原理
  • 1.3、卡頓產(chǎn)生的原因


    卡頓產(chǎn)生的原因:CPU與GPU的消耗時(shí)間太長
    • 卡頓解決的主要思路:盡可能減少CPU元咙、GPU資源消耗
    • 按照60FPS(1秒鐘刷新60幀)的刷幀率梯影,每隔16ms(1000s/60 = 16ms)就會(huì)有一次VSync信號(hào),就可以保證不會(huì)卡,也不會(huì)掉幀

二庶香、卡頓優(yōu)化 - CPU

  • 2.1甲棍、盡量用輕量級(jí)的對(duì)象,比如用不到事件處理的地方赶掖,可以考慮使用CALayer取代UIView
  • 2.2感猛、不要頻繁地調(diào)用UIView的相關(guān)屬性称诗,比如frame主经、bounds、transform等屬性硬纤,盡量減少不必要的修改
  • 2.3膳灶、盡量提前計(jì)算好布局咱士,在有需要時(shí)一次性調(diào)整對(duì)應(yīng)的屬性,不要多次修改屬性
  • 2.4轧钓、Autolayout會(huì)比直接設(shè)置frame消耗更多的CPU資源
  • 2.5序厉、圖片的size最好剛好跟UIImageView的size保持一致
  • 2.6、控制一下線程的最大并發(fā)數(shù)量
  • 2.7毕箍、盡量把耗時(shí)的操作放到子線程
    • 文本處理(尺寸計(jì)算脂矫、繪制)
    • 圖片處理(解碼、繪制)

三霉晕、卡頓優(yōu)化 - GPU

  • 3.1庭再、盡量避免短時(shí)間內(nèi)大量圖片的顯示,盡可能將多張圖片合成一張進(jìn)行顯示
  • 3.2牺堰、GPU能處理的最大紋理尺寸是4096x4096拄轻,一旦超過這個(gè)尺寸,就會(huì)占用CPU資源進(jìn)行處理伟葫,所以紋理盡量不要超過這個(gè)尺寸
  • 3.3恨搓、盡量減少視圖數(shù)量和層次
  • 3.4、減少透明的視圖(alpha<1)筏养,不透明的就設(shè)置opaque為YES(默認(rèn)就是YES)
  • 3.5斧抱、盡量避免出現(xiàn)離屏渲染
  • 3.6、離屏渲染
    • 在OpenGL中渐溶,GPU有2種渲染方式
      On-Screen Rendering:當(dāng)前屏幕渲染辉浦,在當(dāng)前用于顯示的屏幕緩沖區(qū)進(jìn)行渲染操作
      Off-Screen Rendering:離屏渲染,在當(dāng)前屏幕緩沖區(qū)以外新開辟一個(gè)緩沖區(qū)進(jìn)行渲染操作

    • 離屏渲染消耗性能的原因
      需要?jiǎng)?chuàng)建新的緩沖區(qū)
      離屏渲染的整個(gè)過程茎辐,需要多次切換上下文環(huán)境宪郊,先是從當(dāng)前屏幕(On-Screen)切換到離屏(Off-Screen)掂恕;等到離屏渲染結(jié)束以后,將離屏緩沖區(qū)的渲染結(jié)果顯示到屏幕上弛槐,又需要將上下文環(huán)境從離屏切換到當(dāng)前屏幕

    • 哪些操作會(huì)觸發(fā)離屏渲染懊亡?

      • 光柵化,layer.shouldRasterize = YES
      • 遮罩乎串,layer.mask
      • 圓角店枣,同時(shí)設(shè)置layer.masksToBounds = YES、layer.cornerRadius大于0叹誉,可以考慮通過CoreGraphics繪制裁剪圓角鸯两,或者叫美工提供圓角圖片
      • 陰影,layer.shadowXXX桂对,如果設(shè)置了layer.shadowPath就不會(huì)產(chǎn)生離屏渲染

四甩卓、耗電優(yōu)化

  • 4.1、耗電的主要來源

    耗電的主要來源

    • CPU處理蕉斜,Processing
    • 網(wǎng)絡(luò)逾柿,Networking
    • 定位,Location
    • 圖像宅此,Graphics
  • 4.2机错、耗電優(yōu)化

    • CPU處理,Processing
      • 盡可能降低CPU父腕、GPU功耗
    • 少用定時(shí)器
    • 優(yōu)化I/O操作
      • 盡量不要頻繁寫入小數(shù)據(jù)弱匪,最好批量一次性寫入
      • 讀寫大量重要數(shù)據(jù)時(shí),考慮用dispatch_io璧亮,其提供了基于GCD的異步操作文件I/O的API萧诫。用dispatch_io系統(tǒng)會(huì)優(yōu)化磁盤訪問
      • 數(shù)據(jù)量比較大的,建議使用數(shù)據(jù)庫(比如SQLite枝嘶、CoreData)
    • 網(wǎng)絡(luò)優(yōu)化
      • 減少帘饶、壓縮網(wǎng)絡(luò)數(shù)據(jù)
      • 如果多次請(qǐng)求的結(jié)果是相同的,盡量使用緩存
      • 使用斷點(diǎn)續(xù)傳群扶,否則網(wǎng)絡(luò)不穩(wěn)定時(shí)可能多次傳輸相同的內(nèi)容
      • 網(wǎng)絡(luò)不可用時(shí)及刻,不要嘗試執(zhí)行網(wǎng)絡(luò)請(qǐng)求
      • 讓用戶可以取消長時(shí)間運(yùn)行或者速度很慢的網(wǎng)絡(luò)操作,設(shè)置合適的超時(shí)時(shí)間
      • 批量傳輸竞阐,比如缴饭,下載視頻流時(shí),不要傳輸很小的數(shù)據(jù)包骆莹,直接下載整個(gè)文件或者一大塊一大塊地下載颗搂。如果下載廣告,一次性多下載一些汪疮,然后再慢慢展示峭火。如果下載電子郵件毁习,一次下載多封智嚷,不要一封一封地下載
    • 定位優(yōu)化
      • 如果只是需要快速確定用戶位置卖丸,最好用CLLocationManager的requestLocation方法。定位完成后盏道,會(huì)自動(dòng)讓定位硬件斷電
      • 如果不是導(dǎo)航應(yīng)用稍浆,盡量不要實(shí)時(shí)更新位置,定位完畢就關(guān)掉定位服務(wù)
      • 盡量降低定位精度猜嘱,比如盡量不要使用精度最高的kCLLocationAccuracyBest
      • 需要后臺(tái)定位時(shí)衅枫,盡量設(shè)置pausesLocationUpdatesAutomatically為YES,如果用戶不太可能移動(dòng)的時(shí)候系統(tǒng)會(huì)自動(dòng)暫停位置更新
      • 盡量不要使用startMonitoringSignificantLocationChanges朗伶,優(yōu)先考慮startMonitoringForRegion:
    • 硬件檢測優(yōu)化
      • 用戶移動(dòng)弦撩、搖晃、傾斜設(shè)備時(shí)论皆,會(huì)產(chǎn)生動(dòng)作(motion)事件益楼,這些事件由加速度計(jì)、陀螺儀点晴、磁力計(jì)等硬件檢測感凤。在不需要檢測的場合,應(yīng)該及時(shí)關(guān)閉這些硬件
  • 五粒督、APP的啟動(dòng)的優(yōu)化

    • 5.1陪竿、APP的啟動(dòng)可以分為2種
      • 冷啟動(dòng)(Cold Launch):從零開始啟動(dòng)APP
      • 熱啟動(dòng)(Warm Launch):APP已經(jīng)在內(nèi)存中,在后臺(tái)存活著屠橄,再次點(diǎn)擊圖標(biāo)啟動(dòng)APP
    • 5.2族跛、APP啟動(dòng)時(shí)間的優(yōu)化,主要是針對(duì)冷啟動(dòng)進(jìn)行優(yōu)化
      • 通過添加環(huán)境變量可以打印出APP的啟動(dòng)時(shí)間分析(Product -> Scheme-> Edit scheme -> Run -> Arguments->Environment Variables下添加)
      • DYLD_PRINT_STATISTICS設(shè)置為1锐墙,提示在:iOS 13之后這個(gè)設(shè)置就無效了
        DYLD_PRINT_STATISTICS 大概的耗時(shí)統(tǒng)計(jì)
      • 如果需要更詳細(xì)的信息礁哄,那就將DYLD_PRINT_STATISTICS_DETAILS設(shè)置為1
        更詳細(xì)的信息
    • 5.3、APP的冷啟動(dòng)可以概括為3大階段


      APP的冷啟動(dòng)可以概括為3大階段
      • dyld(dynamic link editor)贮匕,Apple的動(dòng)態(tài)鏈接器姐仅,可以用來裝載Mach-O文件(可執(zhí)行文件、動(dòng)態(tài)庫等)
        • 啟動(dòng)APP時(shí)刻盐,dyld所做的事情有掏膏,1.裝載APP的可執(zhí)行文件,同時(shí)會(huì)遞歸加載所有依賴的動(dòng)態(tài)庫敦锌,2.當(dāng)dyld把可執(zhí)行文件馒疹、動(dòng)態(tài)庫都裝載完畢后,會(huì)通知Runtime進(jìn)行下一步的處理
      • runtime乙墙,啟動(dòng)APP時(shí)所做的事情有
        • 調(diào)用map_images進(jìn)行可執(zhí)行文件內(nèi)容的解析和處理
        • 在load_images中調(diào)用call_load_methods颖变,調(diào)用所有Class和Category的+load方法
        • 進(jìn)行各種objc結(jié)構(gòu)的初始化(注冊(cè)O(shè)bjc類 生均、初始化類對(duì)象等等)
        • 調(diào)用C++靜態(tài)初始化器和attribute((constructor))修飾的函數(shù)
        • 到此為止,可執(zhí)行文件和動(dòng)態(tài)庫中所有的符號(hào)(Class腥刹,Protocol马胧,Selector,IMP衔峰,…)都已經(jīng)按格式成功加載到內(nèi)存中佩脊,被runtime 所管理
      • main
        • APP的啟動(dòng)由dyld主導(dǎo),將可執(zhí)行文件加載到內(nèi)存垫卤,順便加載所有依賴的動(dòng)態(tài)庫
        • 并由runtime負(fù)責(zé)加載成objc定義的結(jié)構(gòu)
        • 所有初始化工作結(jié)束后威彰,dyld就會(huì)調(diào)用main函數(shù)
        • 接下來就是UIApplicationMain函數(shù),AppDelegateapplication:didFinishLaunchingWithOptions:方法
    • 5.4穴肘、APP的啟動(dòng)優(yōu)化方案(按照不同的階段)
      • dyld

        • 減少動(dòng)態(tài)庫歇盼、合并一些動(dòng)態(tài)庫(定期清理不必要的動(dòng)態(tài)庫)
        • 減少Objc類、分類的數(shù)量评抚、減少Selector數(shù)量(定期清理不必要的類豹缀、分類)
        • 減少C++虛函數(shù)數(shù)量
        • Swift盡量使用struct
      • runtime

        • 用+initialize方法和dispatch_once取代所有的attribute((constructor))、C++靜態(tài)構(gòu)造器盈咳、ObjC的+load
          initialize取代initload方法
      • main

        • 在不影響用戶體驗(yàn)的前提下耿眉,盡可能將一些操作延遲,不要全部都放在finishLaunching方法中
        • 按需加載(舉個(gè)例子鱼响,剛進(jìn)入app只需要加載首頁的收據(jù)就好了鸣剪,不需要加載所有頁面的數(shù)據(jù))
  • 六、安裝包瘦身

    • 6.1丈积、安裝包(IPA)主要由可執(zhí)行文件筐骇、資源組成
    • 6.2、資源(圖片江滨、音頻铛纬、視頻等)
      • 采取無損壓縮(資源質(zhì)量不會(huì)發(fā)生變化,但是大小會(huì)變小唬滑,必須圖片用 png圖片壓縮神器)
      • 去除沒有用到的資源告唆,下面是我測試圖片資源的情況,我在桌面有一個(gè)項(xiàng)目CPU&GPU,里面放了幾張圖片晶密,都沒有使用
        CPU&GPU

        利用LSUnusedResources檢測沒有使用的資源
    • 6.3擒悬、可執(zhí)行文件瘦身
      • 編譯器優(yōu)化
        • (1)Strip Linked ProductMake Strings Read-Only稻艰、Symbols Hidden by Default設(shè)置為YES懂牧,xcode 默認(rèn)這些都是 YES
          編譯器優(yōu)化
        • (2)去掉異常支持,Enable C++ Exceptions尊勿、Enable Objective-C Exceptions設(shè)置為NO僧凤, Other C Flags添加-fno-exceptions
          Enable C++ Exceptions
        • (3)利用 AppCode 檢測未使用的代碼:菜單欄 ->Code->InspectCode
        • (4)編寫LLVM插件檢測出重復(fù)代碼躯保、未被調(diào)用的代碼(這個(gè)比較難)
        • (5) LinkMap旋膳,生成LinkMap文件,可以查看 可執(zhí)行文件的具體組成(生成文件后記得回復(fù)原樣)
          LinkMap

          上面的地址我寫為了/Users/wangchong/Desktop/,運(yùn)行之后再桌面生成了CPU&GPU-LinkMap-normal-x86_64.txt文件
          CPU&GPU-LinkMap-normal-x86_64.txt
        • 分析LinkMap文件


          分析LinkMap文件
        • 借助第三方工具解析LinkMap文件:https://github.com/huanxsd/LinkMap
          解析LinkMap文件
  • 七吻氧、下面是幾個(gè)問題(不懂的看上面)

    • 你在項(xiàng)目中是怎么優(yōu)化內(nèi)存的溺忧?
    • 優(yōu)化你是從哪幾方面著手咏连?
    • 列表卡頓的原因可能有哪些盯孙?你平時(shí)是怎么優(yōu)化的?
    • 遇到tableView卡頓嘛祟滴?會(huì)造成卡頓的原因大致有哪些振惰?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市垄懂,隨后出現(xiàn)的幾起案子骑晶,更是在濱河造成了極大的恐慌,老刑警劉巖草慧,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桶蛔,死亡現(xiàn)場離奇詭異,居然都是意外死亡漫谷,警方通過查閱死者的電腦和手機(jī)仔雷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舔示,“玉大人碟婆,你說我怎么就攤上這事√璧荆” “怎么了竖共?”我有些...
    開封第一講書人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長俺祠。 經(jīng)常有香客問我公给,道長,這世上最難降的妖魔是什么蜘渣? 我笑而不...
    開封第一講書人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任淌铐,我火速辦了婚禮,結(jié)果婚禮上宋梧,老公的妹妹穿的比我還像新娘匣沼。我一直安慰自己,他們只是感情好捂龄,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開白布释涛。 她就那樣靜靜地躺著加叁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪唇撬。 梳的紋絲不亂的頭發(fā)上它匕,一...
    開封第一講書人閱讀 52,785評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音窖认,去河邊找鬼豫柬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛扑浸,可吹牛的內(nèi)容都是我干的烧给。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼喝噪,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼础嫡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起酝惧,我...
    開封第一講書人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤榴鼎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后晚唇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巫财,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年哩陕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了平项。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡萌踱,死狀恐怖葵礼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情并鸵,我是刑警寧澤鸳粉,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站园担,受9級(jí)特大地震影響届谈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弯汰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一艰山、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧咏闪,春花似錦曙搬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽征讲。三九已至,卻和暖如春橡娄,著一層夾襖步出監(jiān)牢的瞬間诗箍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來泰國打工挽唉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留滤祖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓瓶籽,卻偏偏與公主長得像匠童,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子棘劣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • CPU和GPU 在屏幕成像的過程中俏让,CPU和GPU起著至關(guān)重要的作用 CPU(Central Processing...
    曹來東閱讀 334評(píng)論 0 0
  • CPU和GPU 在屏幕成像的過程中,CPU和GPU起著至關(guān)重要的作用==CPU==(Central Process...
    斑駁的流年無法釋懷閱讀 1,627評(píng)論 0 26
  • 用兩張圖告訴你茬暇,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 12,754評(píng)論 2 59
  • 面試中常常問道性能優(yōu)化的問題寡喝,其中有幾個(gè)主要的 你在項(xiàng)目中是怎么優(yōu)化內(nèi)存的糙俗? 優(yōu)化你是從哪幾方面著手? 列表卡頓的...
    Rathen閱讀 27,089評(píng)論 5 102
  • 一预鬓、卡頓優(yōu)化 在屏幕成像的過程中巧骚,CPU和GPU起著至關(guān)重要的作用。CPU(Central Processing ...
    伶俐ll閱讀 814評(píng)論 0 1