Qt Quick 2 のスピード

Qt5 の目玉である Qt Quick 2 は OpenGL や QML Scene Graph、V8 JavaScript エンジンの採用でパフォーマンスを Qt Quick 1 から大幅に向上させています。とは言うものの、バグや Mesa のようなソフトウェア 3D エンジンの利用などで Qt Quick 1 よりも遅くなることもあります。

は Qt Quick 2 でアプリが遅くなったことに関する質問から始まったやりとりですが、その中で Qt5 では上記以外にどのようなテクニックを使って Qt Quick のパフォーマンスの改善を行っているかの説明があります。興味深い内容ですので、要約してみましょう。

  • オブジェクトツリーの構築(QMLのパース?)は遅延処理を入れることで若干速くなりました
  • QObjectの利用の削減やビットフィールドの利用などでメモリ使用量を削減
  • (V8 エンジンの採用により) JavaScript の高速化。ただし、プロパティへのアクセスなどは従来とほぼ同様

Qt Quick 1 の各要素はすべて QObject がベースとなっていました。プロパティは QObject のプロパティですし、バインディングはシグナル・スロットによるものでした。しかし、すべてを QObject を通す必要があるため、そこにオーバーヘッドが生じてしまいます.Qt Quick 2 では QObject を使わないバインディングのシステムを構築することで高速化を図りました。

また、バインディングの最適化の仕組みが大きく変わりました。Qt Quick 1 でも QDeclarativeCompiledBinding という内部クラスを用いてバインディングする式を最適化して保持していましたが、Qt Quick 2 ではこれが v4 と言う新たな仕組みに置き換わっています。v4 では従来よりも多くの式を扱うことが出来、V8 で式を評価するよりも軽量です。

例えば、スタイルの仕組みとして .pragma library な JavaScript のライブラリを各 QML で共有する場合、v4 でバインディングを評価することは出来ません。しかし、QObject のコンテキストを通して評価する場合、ほとんどのケースで v4 を用いることが出来るため、かなりの高速化が図れます。あるベンチマークでは 25% ほど高速化したそうです。

Qt Quick 2 では v4 と V8 を組み合わせることでバインディングも含めた JavaScript の実行が充分に速くなりました。また、v4 には llvm 等を用いて JIT で更に高速化する v4vm プロジェクトが Qt Playground で開発されています。Qt 5.1 や 5.2 (あるいはそれ以降)で採用されれば、さらに Qt Quick は高速になることでしょう。

上記の解説は 5.0 での状況なので今後変わっていくでしょうが、ある程度頭に入れておくと Qt Quick のプログラムのパフォーマンスを改善する助けとなるかもしれません。

最後に、QML でパフォーマンスを改善するためのドキュメントのリンクを書いておきます。

たとえば、 QML_COMPILER_STATS 環境変数をセットしておくと、QML の各式が最適化されたのかどうかが表示されます。

色々と省略した説明になってしまいましたが、興味がある人はさらに調べてみるのも面白いかと。もしくは質問してください。希望があるようでしたら QML Scene Graph について、新たに説明し直してみるのも面白いかもしれません。

コメントを残す