🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

近期,Android 官方宣布了 Android Runtime 在編譯時間上實現了 18% 的顯著優化,同時不犧牲編譯代碼的質量,也沒有增加峰值記憶體使用,換句話說,這屬於是一個“速度提升 + 零損失”的優化成果。

實際上這個調整作為 2025 年的關鍵 KPI,目前已經實現了分階段 rollout:部分優化已經在 2025 年 6 月的 Android 發布中上線,其餘會在年底發布中完成,所有運行 Android 12 及以上版本的用戶都可以通過 mainline 更新得到這些改進。

“mainline 更新”( Project Mainline / Google Play System Updates) 是一種模組化更新機制,它支持 Google 透過 Google Play 直接更新 Android 系統的核心組件(如 Android Runtime、媒體框架、安全模組等),這個更新不需要用戶等待 OTA。

而這次優化更加具體的說就是:

  • 編譯時間減少了 18%
  • 對編譯器最終輸出質量沒有負面影響
  • 沒有出現記憶體回歸(就是提升過程中不增加記憶體占用峰值)

並且,這些改進對於 JIT 和 AOT(預先編譯)都有用,當然這裡提到的 Android Runtime(ART)“編譯速度”不是你在本地用 Gradle 構建 APK 的速度,而是「設備端 ART 對 app 字節碼進行 AOT / JIT 編譯的速度」,一般而言針對 ART 內部的“編譯器執行速度”會有:

  • JIT 編譯速度
  • AOT / dex2oat 編譯速度
  • 編譯器各個 IR / 優化 pass 的執行時間

例如在 ART 裡有很多 pass(比如 GVN、某些資料流分析),每次都會遍歷 IR,即使當前方法根本不滿足優化條件也會完整跑一遍邏輯,這種行為帶來的開銷並沒有產生收益:

官方提到,在之前有一個名為全局值編號 (GVN) 的階段,這個過程裡它有一個名為 Kill 的方法,這個方法會根據過濾器刪除一些節點,由於它需要遍歷所有節點並逐個檢查,因此非常耗時,而事實上無論當時有多少節點存活,其實都能預先知道檢查結果為 false,那麼在這種情況下完全可以跳過遍歷,從而將性能消耗從 1.023% 降低到約 0.3%,並將 GVN 的運行時間縮短約 15%。

其他的一些案例,包括有:

FindReferenceInfoOf 的查找優化

LoadStoreAnalysis 階段的方法 FindReferenceInfoOf 原本使用線性搜索 O(n) 在向量中查找,而現在將資料結構改為以指令 ID 為索引,实现 O(1) 查找,並預分配向量以避免 resize, 從而在這個階段加速 34 - 66%,總編譯時間提升 0.5-1.8%,雖然增加了一個計數欄位,但峰值記憶體沒有增加

結構調整

代碼庫中使用了一個自定義的 HashSet,多年前是為了處理極少數的大型集合而優化的,但現在的用法變成了創建大量小型的、短生命周期的集合,所以本地調整實現以適應“小而短”的用法,減少創建和銷毀開銷,從而讓編譯時間提升 1.3-2%,且記憶體使用量反而下降了 0.5-1%

還有通過將資料結構以引用方式傳遞給 lambda 表達式,避免了資料結構的複製,從而將編譯時間縮短了約 0.5% 到 1% ,這一點在最初的代碼審查中被忽略了,並在代碼庫中保留了多年:

image

內聯 (Inlining) 檢查

編譯器為了性能會內聯函數,原本的流程是先計算大量資料,最後再做“最終檢查”(如指令數、寄存器需求)決定是否內聯,而現在將這些檢查從“計算後”移到了“計算前”作為啟發式規則(Heuristics),避免了大量無效計算,僅指令數檢查一項的移動就帶來了約 2% 的提升

事實上官方在進行這些調整時也遇到了不少問題,因為即使你發現某個區域佔用了大量編譯時間,並且投入了開發時間嘗試改進,有時也找不到解決方案,當你修改了 A 問題後,自然而然就帶了 B 問題,比如:

  • 記憶體回歸 :在優化“輸出寫入”階段時,團隊通過快取計算值來加速(原本預計提升 1.3-2.8%),但自動化測試時發現,額外的快取資料結構導致了記憶體使用量的顯著增加
  • 歷史遺留負擔 :許多低效代碼是因為歷史原因遺留下來的(比如上述的 HashSet),或者是因為代碼審查疏忽(將物件按值傳遞而不是按引用傳遞)
  • 複雜度的權衡 :某些優化方案可能過於複雜,或者會增加代碼維護難度

針對這些問題,官方進行了一系列的調整嘗試:

  • 重構解決記憶體回歸 :針對“輸出寫入”階段的記憶體問題,本次直接重構了該階段的邏輯,這裡設計了一種新方案,移除了兩個冗餘資料結構中的一個,這不僅解決了記憶體回退問題,還進一步提升了 0.5-1.8% 的速度 image
  • 使用 pprof 進行深度分析 :利用 pprof 工具生成 Flame Graph 和 Bottom-up 視圖,精確定位那些“隱形”的開銷(如頻繁的 Kill 方法或意外的物件拷貝) imageimage
  • “快速迭代”策略 :為了節省開發時間,先用原型(Prototype)在典型應用(First-party apps, Android OS)上快速驗證想法,確認收益後再進行完整的工程實現和測試
  • 利用全新 C++ 特性 :比如使用 BitVectorView 替代可變長的 BitVector,並利用模板化實現讓 Union() 操作在 64 位平台上一次處理兩倍的位數

除此之外還有:

最後

最後,看不懂不要緊,只需要知道它很厲害,並且還能讓 Android 12 以後的機器變得更快,在用戶端體現出來就是:

  • app 啟動更快
  • 冷啟動更少卡頓
  • 低端機更友好
  • 安裝 / 更新變快

同時也展示了教科書級別的優化策略,不僅要看速度,更要看記憶體、穩定性、可維護性等綜合指標,所以官方這份報告不僅僅是技術公告,更是一份優秀的編譯器工程的案例研究。

參考連結


原文出處:https://juejin.cn/post/7583980250733969471


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝13   💬9   ❤️5
353
🥈
我愛JS
📝1   💬8   ❤️2
60
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付