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