メインコンテンツまでスキップ

ベンチマーク

同じ画面を YAUI、uGUI (TextMeshPro)、UI Toolkit で組み、モバイル端末で計測しました。コードとシーンはリポジトリの Assets/Benchmarks にあります。

UI によって増えるフレームあたりの時間: YAUI、uGUI、UI ToolkitUI によって増えるフレームあたりの時間: YAUI、uGUI、UI Toolkit

概要​

  • ほとんどのシナリオで YAUI のメインスレッドのコストが最も小さくなります。 変更のないフレームのコストはゼロで、色の変更・要素の移動・ヒットテストは 0.25 ms 未満です。
  • テキストの変更は uGUI の約半分、UI Toolkit の約 1/5 です。
  • レイアウトは uGUI の Layout Group の約 7 倍速いものの、UI Toolkit より遅くなります (増分 10.7 ms 対 6.5 ms)。
  • GPU 時間は uGUI より長く (約 1.7〜2.3 倍)、これは Uber シェーダーのコストです。UI Toolkit と比べると、グリッドでは短く、リストではほぼ同じです。

計測環境​

  • 端末: Google Pixel 5 (Snapdragon 765G、Adreno 620)、Android 14
  • グラフィックス API: Vulkan
  • 画面: 1080 x 2340、縦。UI はネイティブ解像度で描画
  • ビルド: IL2CPP、ARM64、リリースビルド
  • Unity: 6000.7.0b2、URP 17.7.0
  • YAUI: 0.2.0

各シナリオはウォームアップ 120 フレームのあと 600 フレームを計測します。全シナリオを 3 回実行し、シナリオごとに 3 つのシステムを続けて実行します。発熱の影響が偏らないよう、その順番は回ごとに入れ替えます。値は、フレームの中央値の 3 回分の中央値です。

シナリオ​

シナリオ内容
Grid画面を埋める 1,500 セル (30 x 50)。セルは角丸のパネル、丸いアイコン、数字のラベルで、要素は 4,500 個
Grid: no changes変化なし
Grid: 10% change color10% のセルの背景色を毎フレーム変更
Grid: 10% move10% のセルを毎フレーム移動 (レイアウトなし)
Grid: 10% change text10% のセルのラベルを毎フレーム変更 (桁数は同じ)
Grid: 10 hit tests変化なし。毎フレーム 10 回のヒットテスト
Listスクロールビューの中の 500 行 (仮想化なし)。行は角丸のパネル、丸いアイコン、タイトル、値
List: scroll毎フレームスクロール
List: 10% relayout10% の行のタイトルを毎フレーム 1 行と 2 行で切り替え、レイアウトをやり直させる

各システムでは、見た目を揃えたうえで、それぞれの通常の方法で画面を組んでいます。

YAUIuGUI + TextMeshProUI Toolkit
Grid折り返しのある flex の行アンカー (Layout Group なし。uGUI で最も速い方法)折り返しのある flex の行
ListYauiScrollView の中の flex の列ScrollRect、RectMask2D、Vertical / Horizontal Layout GroupScrollView
角丸ボックスのスタイル9 スライスのスプライト (アトラスのように 1 枚のテクスチャから)border-radius
テキストYauiTextTextMeshProLabel
最適化アイコンとラベルはレイキャストの対象外定番のもの: 変化するセルを子 Canvas に分離、アイコンとラベルはレイキャストの対象外、isTextObjectScaleStatic変化するセルに Usage Hints、アイコンとラベルはピッキングの対象外
ヒットテストEventSystem.RaycastAllEventSystem.RaycastAllIPanel.Pick

結果​

CPU​

フレームあたりのメインスレッドの時間 (ミリ秒、表示の待ちを除く)。空のシーンからの増分を括弧内に示します。

シナリオYAUIuGUI + TextMeshProUI Toolkit
空のシーン2.572.572.57
Grid: no changes2.30 (±0)3.17 (+0.61)2.96 (+0.40)
Grid: 10% change color2.62 (+0.06)5.62 (+3.05)3.77 (+1.21)
Grid: 10% move2.78 (+0.21)4.42 (+1.85)4.37 (+1.80)
Grid: 10% change text4.81 (+2.25)6.97 (+4.41)14.98 (+12.41)
Grid: 10 hit tests2.41 (±0)7.83 (+5.26)4.82 (+2.25)
List: scroll3.16 (+0.59)6.93 (+4.36)3.42 (+0.86)
List: 10% relayout13.24 (+10.67)76.74 (+74.17)9.02 (+6.45)

空のシーンをわずかに下回る値は誤差の範囲なので、±0 と表記しています。

描画スレッドはどのシナリオでも 0.5〜1.8 ms で、システム間の差は小さくなっています。

GPU​

GPU は負荷に応じてクロックを変えるため、異なるシーンの GPU 時間はそのままでは比べられません。ここでは、重い全画面のパスで GPU を最高クロックに保ち、そのパスだけのときとの差を UI のコストとしています。

シナリオYAUIuGUI + TextMeshProUI Toolkit
Grid+5.20+2.98+8.69
List+3.31+1.45+3.01

通常のフレームのようにクロックが低いときは、同じ処理にもっと時間がかかります。

注意点​

  • テキスト: テキストの変更にかかる時間は実行ごとにばらつきます (YAUI の合計で 4.5〜7.5 ms)。
  • レイアウト: YAUI はメインスレッドでレイアウトのジョブを待ちます。リストの行は高さが内容で決まるためレイアウトの境界にならず、リスト全体がレイアウトし直されます。
  • 「List: 10% relayout」では、2 行でも行の最小の高さに収まるため、行の高さはほぼ変わりません。
  • UI Toolkit のヒットテスト (Pick) は最前面の要素だけを返します。ほかの 2 つは、その点にあるすべての要素を返します。
  • 結果は 1 台の端末のものです。端末、グラフィックス API、内容によって変わります。

ベンチマークの実行​

  1. TextMeshPro の Essential Resources をインポートします (Window > TextMeshPro > Import TMP Essential Resources)。
  2. Assets/Benchmarks/Comparison/ComparisonBenchmark.unity だけを含めて端末向けにビルドします。Development Build では、プロファイラのマーカーによる内訳も記録されます。
  3. アプリは全シナリオを実行し (約 25 分)、結果を表示して、CSV として Application.persistentDataPath に書き出します。
  4. Assets/Benchmarks/Tools~/chart.py は CSV から表を出力し、グラフを描きます。

このページの計測結果の生データは Assets/Benchmarks/Results~ にあります。