在低端的設備上編寫嵌入式程序的時候,Qt for Windows CE 和 Qt for Embedded Linux 都提供了大量的選項,這些選項通過很多不同的權衡來幫助減少內存和CPU的需求,這些選項非常廣泛,從編程風格,鏈接到內存分配。
請注意,最直接的節省資源的做法是不要去編譯不需要使用的功能模塊,請參考”Fine tuning features”一文,它提供了非常詳細的說明
本文一共分爲如下幾個專題來講述:
- 編程風格
- 靜態鏈接 vs 動態鏈接
- 另一種可選擇的內存分配方式
- 繞開 “Backing store”
編程風格
一次性創建 dialog 和 widget,然後在需要的時候調用 QWidget::show() 和 QWidget::hide()
方法,而不是每次在需要使用的時候,都去創建它們,在不需要的時候就刪除它們。避免應用程序啓動過程緩慢,不要在一開始的時候就把 dialog 和
widget 都創建好,而是在第一次需要使用它們的時候再去創建它們。所有這些工作都能提高 CPU 的效率,當然,它們需要佔用一些內存。
靜態鏈接 vs 動態鏈接
有很多CPU和內存使用ELF(Executable and Linking
Format)鏈接過程,相對於那種有很多的可執行模塊然後在運行的過程中動態鏈接的方法而言,在編譯一個應用程序的時候使用靜態鏈接可以節省很多的資
源。所有的程序都被靜態的編譯鏈接成了一個可執行文件中。
這個方法可以加速應用程序的啓動速度,並且可以減少內存消耗,付出的代價是靈活性(當添加一個模塊的時候,必須重新編譯這個單一的可執行程序)和程序的健壯性(如果一個模塊有bug,那麼整個程序都將收到影響)。
創建靜態鏈接
在運行 configure 命令的時候,使用 –static 編譯選項,這樣就可以把整個 Qt 編譯成靜態鏈接庫。
./configure –static
爲了編譯一組應用程序到成一個單一的應用程序,把每一個應用程序都定義成一個獨立的Widget(或者是一個widget的集合),並且在main()函
數中包含儘可能少的代碼。然後再寫另外一個應用程序提供一種在這些不同的應用程序之間切換的方式。Qt Extended
平臺是使用這個方法的最好的例子,它可以被編譯成一組動態鏈接的可執行文件,也可以編譯成一個單一的靜態鏈接程序。
注意:一個應用程序還是會動態的去鏈接標準的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 語言的內存分配方式。
繞過 ”Backing store”
在繪圖輸出的時候,Qt會使用一個”Backing store”的概念,比如,一個繪圖緩衝區,爲了減少界面閃爍,並且支持一個圖形操作,比如混合等。
對於每一個客戶端程序的缺省行爲是,程序把自己的widget畫到一塊內存中,然後Windows
Server負責把這段內容放到屏幕上去。但是如果是定義良好的硬件的話,並且在嵌入式設備中經常都是這種情況,繞過這個過程就會非常有用,這樣就允許客
戶端應用程序直接操作底層硬件,這裏有兩種方法去完成直接繪製,第一種方法是爲每一個widget都設置Qt::WA_PaintOnScreen窗口屬
性;另一種方法是使用QDirectPainter類來在framebuffer上面保留一塊區域。更多的詳細信息請參考”Architecture”文
檔中的”direct painting”一節。
---------------------------------------------------------------
聲明:本文是Qt核心技術論壇翻譯文章,如需轉載,請註明本文鏈接:
http://www.insideqt.com/bbs/viewthread.php?tid=31
注:本文翻譯自 Qt 4.5.0 for Embedded Linux 的聯機幫助文檔,”Qt Performance Tuning”
---------------------------------------------------------------