關於Qt性能的損失,有沒有一個可以量化的概念?

如題


內存方面,自定義的繼承QObject和聲明QObject宏的類,都會生成其靜態的QMeatObject的類的信息說明,裡面包含類的一些信息,去實現元信息和反射。

還有鏈接信號槽,是通過一個QVector保存的。還有Qt的類大部分都是d-p指針設計的。

QString內部是UTF-16編碼的,所有字元都是兩個位元組的。

效率方面:

1、QTL部分,Qt的容器和stl的容器部分實現不是一致的,效率上整體沒有很大的差別。關於這個:http://marcmutz.wordpress.com/effective-qt/containers/ 這裡有說明(要翻牆)

我翻譯了部分: http://www.dushibaiyu.com/2014/11/stl-vs-qtl-1.html[翻譯]理解Qt容器:STL VS QTL(二)——迭代器[翻譯]理解Qt容器:STL VS QTL(三)——類型系統 和其他處理

2、關於信號槽(很多吐槽Qt就是說的這個):(根據Qt5實現分析的)

(1)Qt4語法的,都說是匹配字元串,其實只是鏈接信號槽的用的匹配字元串的方法,通過字元串找到信號和槽再QMeatObject里存的索引位置int類型,還有槽函數的索引,然後調用的時候通過索引號用switch去區分的發射的那個函數,然後取出對應的鏈接槽的list,循環檢測槽函數的參數是否匹配,然後調用槽函數。。這個鏈接時會耗時查找,但是你能有多少信號?這個鏈接也耗時不多,調用的時候耗時主要就是在參數匹配上了,以現在的cpu速度,我不知道怎麼去看出來。

(2)Qt5 語法的,Qt5 的槽函數鏈接和執行是基於模板實現的,函數對象。信號和槽的參數問題是編譯時檢查的,執行效率更高,但是編譯就慢點了。鏈接時也是通過信號的地址找到其的信號索引,至於槽函數直接是生成一個函數對象的,然後調用的時候也是先switch找到發射的信號,取出list,然後逐個調用其儲存的函數對象,所以對於Qt5 語法的信號槽,調用性能損失幾乎可以說無的。

(3)在信號槽調用的時候,還有一些鏈接方式的判斷的,關於這個就還涉及到調用槽函數的縣城問題。鏈接的信號槽的時候,Qt::UniqueConnection的鏈接方式會對已經鏈接過的此先好的槽函數進行遍歷,會有鏈接時的損失。其他鏈接的損失就在上面說過了。

調用時會有是不是當前現成和鏈接方式的判斷,對於直接調用,除了上面分兩種方式分別的多少的教函數指針(對象)直接調用的損失,就還有個鏈接方式和線程的幾個if。

對於線程間通訊的調用,跨線程。信號槽內部也是通過Qt事件循環機制實現的,跨線程就不是時時調用了,主要是安全了,對於性能有沒有損失沒法評論的。對於跨線程阻塞的調用,這個也是事件實現,只是但錢線程會阻塞,這個找不到對應的直接調用的比較,也不好說。

關於信號槽Qt是作何很多方便使用和安全調用,較之函數指針,性能會有損失,但是也沒損失多少的。對於函數對象調用,Qt5語法的調用,幾乎是不損失什麼的。

3、關於GUI那塊:

這塊我就不是很熟悉了,但是說下在win下,教於MFC,Qt會把win的消息封裝成Qt的事件,有多了一層封裝。對於很多東西為了跨平台都有二次封裝的,這個二次封裝很多都會導致教你直接調用會多幾次入棧出棧,一般來說,要到棧級性能壓榨的應用,你也都是自己造輪子多了吧?

對QML,那就是一個默認解釋執行的,但是其默認是openGL加速的,對於計算機級別的任務會有損失,但是繪圖不弱的。

----------------------------------------------------------------------------------------------------------------

個人還是菜鳥,這只是我能想到和以為的一些較於直接調用我理解的損失、、

如有錯誤請指出。


我告訴你沒有損失你信不信。

你要實現這些功能,必須要付出的代價不能稱之為損失。

C++之父說,c++的原則就是不會讓你為用不到的特性付出代價。Qt也是如此。

你要跨平台,你必須要封裝。你要語言國際化,你必須要用locale和qstring。你要線程安全的界面編程,我想不出比signal/slot更帥氣的實現。

Qt是一個框架,也是一個庫。你可以用,也可以不用;可以全用,也可以挑順眼部分的用。

覺得qstring空間太大,可以用std::string。覺得信號槽慢,可以自己實現函數map。甚至覺得qwidget實現不優雅,可以使用原生的window handle。

說到底,c++給了使用的自由,這就是其比java優雅的地方。不爽了我可以換,同樣功能有很多實現給我選擇,我自己也可以自己造輪子。

Qt只是封了一層,封的好不好你說了算。

Qt做的,你覺得你可以做的更好,這才是損失。

就我個人,看看文檔,瞅瞅源碼,總是覺得可以學習更多。


@Elvis Wang說的好。這叫overhead,叫開銷,不叫損失。你買東西花了五百塊叫開銷,你走在路上丟了五百塊才叫損失。


性能損失,要說沒有,Qt官方也不敢這麼說。Qt的一個核心機制就是信號與槽機制,相比於傳統的回調機制,稍微慢了一點。慢了多少?官方已給出了數據,原文是:「In general, emitting a signal that is connected to some slots, is approximately ten times slower than calling the receivers directly, with non-virtual function calls.」 即信號槽調用比直接回調慢了10倍左右(並非整體性能)。當然這個數據是官方給的,不排除往好里寫。

通常UI程序在小位置損失一些性能,倒也無所謂了。但如果Qt中一個槽函數的信號調用極度頻繁,性能損失積少成多,就不好了,這種情況,盡量避免。

除性能方面,Qt吃內存還是蠻厲害的,一個空對話框程序,就佔了10M-20M內存。相比跨平台領域Qt的主要競爭對手wxWidgets,才占幾M而已。

不計性能損失和內存開銷,Qt的好處還是蠻多的:豐富的文檔和控制項,各種成熟的類,大大加快了開發進度。這樣一比,在UI程序中,Qt利遠大於弊。


推薦閱讀:

Qt 框架哪些方面效率高,哪些方面效率低?
C++單元測試如何實施?
各位都是怎麼進行單元測試的?
MFC 過時了嗎?
如何用c++寫一個簡單的計算器程序?

TAG:圖形用戶界面 | QtC開發框架 | Java | C | C# |