應用程式啟動速度最佳化

來源:互聯網
上載者:User

應用程式啟動速度最佳化
Mac OS/Android下的Static Initializer


Mozilla工程師通過最佳化Static Initializer(靜態初始化,或全域建構函數, Global Constructor)和Binary布局來提升FireFox啟動速度的文章,非常有參考價值。文章中以x86及x86-64平台為基礎,下面加了Mac OS及Android上的binary布局。


什麼是Static Initializer? 簡而言之就是全域C++對象的初始化。有人笑稱一個C++程式的main()函數執行之前,可能該做事都做完了,這就是Static Initializer的影響。如果裡面又有一層層依賴引用,就會大大影響啟動時間。下面是一個樣本程式:


MyClass oneClass(0x010203);const MyClass twoClass(0x010204);attribute ((constructor)) void foo(void){    printf(“foo is running and printf is available at this point\n”);}int main(int argc, const char * argv[]){  //do something here…}
前兩個對象oneClass和twoClass即是使用了靜態初始化的兩個對象, 而foo函數則通過編譯選項強制放到程式的初始化段(init segement)中,在程式初始化時就會執行。以下即最終在Mac OS上的布局:在Android ARM ELF中則是下面這個布局:

FireFox的最佳化

在Mozilla工程師的文章[連結]中,基於Firefox 4.0b8在x86及x86-64的測試資料發現如下的平均啟動時間:

平均啟動時間(ms) Pages Read Bytes Read
x86 3,228.76 ± 0.57% 4,787 19,607,552
x86-64 3,382.0 ± 0.51% 5,874 24,059,904

使用systemtap[連結]可以得到一個訪問核心庫libxul.so的access pattern:

Static Initializers

在開始時那些垂直的線段正是Static Initializers啟動並執行時間,佔去了不少的時間。解決之道就是減少static initializers,特別留心那些全域變數、靜態變數。

以這種方法分析了一下,一共有237個static initializers,其中147是由cycle collection globals所引入的。經過修正後cycle collection的全域對象降到一個,整個情況並未有大的改觀:

平均啟動時間(ms) Pages Read Bytes Read
x86 3,216.1 ± 0.59% 4,656 19,070,976
x86-64 3,488.14 ± 0.75% 5,759 23,588,864

以下是新的I/O access pattern:

I/O雖然有所降低,其實還有許多其它內容的讀操作在static initialization前已經發生了,所以還有別的工作需要做。

Reordering objects

另一工作即是重新布局binary, 讓核心需要的資料可以儘快擷取。之前Taras的一個研究發現只要做些toolchain上的變更就可以實現。

使用Taras的icegrind做了最佳化後,改進變得明顯了:

平均啟動時間(ms) Pages Read Bytes Read
x86 2,939.18 ± 0.81% 4,129 16,912,384
x86-64 3,247.64 ± 0.68% 5,254 21,520,384

I/O pattern:

Packing Relocations

最後,再可以通過減少relocation段,來最佳化啟動時間。這樣可以有效降低I/O,以及dynamic relocations section,也能減小程式包。我使用的工具在這裡。參考:關於通過調整ELF最佳化啟動時間下面是最終的效果:

平均啟動時間(ms) Pages Read Bytes Read
x86 3,149.32 ± 0.62% 4,443 18,198,528
x86-64 3,191.58 ± 0.62% 4,733 19,386,368

I/O Pattern如下:

這是一個晦澀的主題,非黨值得深入研究,可以從作者提供的連結入手展開。我水平有限,拋磚引玉,期待著更為深入的闡述。

轉載請註明出處: http://blog.csdn.net/horkychen

參考

1. How to Make Startup Suck Less (Also Reduce Memory Usage!)

2. Death by static initialization

3. icegrind - Valgrind Plugin for optimizing Cold Startup

4. Resolving ELF Relocation Name / Symbols

5. Static initializers

6. ELF for ARM Architecture

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.