Qt Embedded性能優化詳解
Qt Embedded和Qt一樣,在4.5版本之后提供了三種不同的授權協議GPL, LGPL和Commercial。長久以來,雖然使用Qt Embedded在作開發,但對Qt Embedded的性能方面不甚關心,并且因為抱著對qtsoftware的信心,也沒仔細去了解如何優化Qt Embedded。直到前段時間,參加了某個全國嵌入式大賽,使用了Qt Embedded4.5.0在s3c2410平臺上,竟然出現了卡機的現象。對于嵌入式開發來說,資源是極為重要的,而現在看來,Qt變得越來越龐大,越來越耗費稀缺的設備資源,這時,優化就變得格外重要了。在Qt Embedded的文檔中有關于性能優化的介紹,我做了簡單地翻譯,希望能給在嵌入式領域使用Qt Embedded的開發者有所幫助。
Qt 性能優化
當在資源稀缺的設備上開發嵌入式應用程序時,Qt for Windows CE 和Qt for Embedded Linux通過調整一系列參數的開啟或關閉來內存及CPU的需求。這些選擇參數方法的范圍主要在編程風格,鏈接方式及內存分配。
著重注意的是,最直接節省資源的辦法是在編譯時去掉不需要的特性。詳細可以見文檔中的fine tuning features部分。
1、編程風格
2、靜態鏈接vs動態鏈接
3、替換內存分配方式
4、繞過后備存放區
編程風格
與其選擇隨時地創造對話框和控件當它們需要時,并且在不再需要時刪除它們,不如一次性地創建,同時在需要的時候使用QWidget::hide()和QWidget::show() 功能函數。為了避免應用程序啟動的緩慢,應該推遲對話框和控件的創建直到需要的時候。所有這樣將改善CPU的性能,所需要付出的只是更多的一點內存,但這會加快運行的效率。
動態 Vs 靜態鏈接
許多CPU和內存是通過ELF (Executable and Linking Format)鏈接進程,重大的節省可以通過靜態編譯程序的方式實現;而不像是在實際執行中,采集與Qt庫有關的部分并且動態鏈接,所有的應用程序將被創建成一個獨立的執行文件,這個文件采用靜態方式鏈接到Qt庫上。
這些將改善程序啟動時間和減少內存占有率,但前提它會損害靈活實用的特性(一旦增加新的應用部分,必須重新編譯一個獨立的執行文件)和程序健壯性(假如一個應用部分有bug,將危害到其他的應用部分)。
建立一個靜態編譯
為了將Qt編譯成為一個靜態庫,在編譯時采用-static參數:
- ./configure –static
為了將應用程序套裝建立為一個一體化的應用,應當設計各個應用作為單獨的控件(或者控件集)并盡可能地使用最少的代碼量在main()函數。然后,設計一個獨立的應用程序可以提高其他應用程序見交互的方法。Qt Extended platform就是采用典型的實例:它既可以使用一系列動態鏈接執行創建,也可以作為單獨的一個靜態的獨立應用程序。
需注意的時,程序仍將動態地鏈接標準C庫以及其它庫,因為在目標平臺上可能會有其他的應用程序使用它們。
當安裝最終客戶端應用程序時,這個方式不一定是個選擇,但是當在為一個受CPU和內存限制的設備開發一個單獨的應用程序套裝時,這個選擇是十分有益的。
替換內存分配方式
在一些平臺上,那些運用C++編譯的庫,在使用“new”和“delete”操作方面有十分差的性能。未來改善內存分配的性能,可以通過以下的功能函數替代實現:
- void *operator new[](size_t size)
- {
- return malloc(size);
- }
- void *operator new(size_t size)
- {
- return malloc(size);
- }
- void operator delete[](void *ptr)
- {
- free(ptr);
- }
- void operator delete[](void *ptr, size_t)
- {
- free(ptr);
- }
- void operator delete(void *ptr)
- {
- free(ptr);
- }
- void operator delete(void *ptr, size_t)
- {
- free(ptr);
- }
以上這些實例顯示了必要的代碼采用C的內存分配。
繞過后備存放區
當運行時,Qt使用了后備存放區。比如,一個繪圖緩存,可以減少閃爍和支持如重疊的圖形操作。
一般,默認的流程是這樣的,對于每個客戶端,將自己的控件傳入內存,同時,服務端負責將這些內容從內存中取出并在屏幕上繪制。但是有些硬件是眾所周知的,同時已經有嵌入式軟件的案例,這些對于繞開后備存放區是很有幫助的,可以運行客戶端直接地熟練地操作硬件。這里有兩種方式來實現直接繪制:第一種方式是對每個控件使用Qt::WA_PaintOnScreen窗口屬性,另一種是使用了QDirectPainter類來保存幀緩存的區域。想獲取更多信息,可以參考architecture 文檔部分的direct painting細節。