ベンチマーク
同じ画面を YAUI、uGUI (TextMeshPro)、UI Toolkit で組み、モバイル端末で計測しました。コードとシーンはリポジトリの Assets/Benchmarks にあります。
概要
- ほとんどのシナリオで YAUI のメインスレッドのコストが最も小さくなります。 変更のないフレームのコストはほぼゼロで、色の変更・要素の移動・ヒットテストは 0.5 ms 以下です。
- テキストの変更は実行ごとにばらつき、uGUI の約半分からほぼ同じ、UI Toolkit の約 1/4〜1/2 です。
- レイアウトは uGUI の Layout Group の約 7 倍速いものの、UI Toolkit より遅くなります (増分 11.7 ms 対 6.9 ms)。
- GPU 時間はグリッドでは uGUI と同じで、リストでは uGUI の約 1.5 倍です (行が 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 以降の main (シェーダーのバリアントと描画の並べ替えを含む、2026 年 9 月 30 日)
各シナリオはウォームアップ 120 フレームのあと 600 フレームを計測します。全シナリオを 3 回実行し、シナリオごとに 3 つのシステムを続けて実行します。発熱の影響が偏らないよう、その順番は回ごとに入れ替えます。値は、フレームの中央値の 3 回分の中央値です。
シナリオ
| シナリオ | 内容 |
|---|---|
| Grid | 画面を埋める 1,500 セル (30 x 50)。セルは角丸のパネル、丸いアイコン、数字のラベルで、要素は 4,500 個 |
| Grid: no changes | 変化なし |
| Grid: 10% change color | 10% のセルの背景色を毎フレーム変更 |
| Grid: 10% move | 10% のセルを毎フレーム移動 (レイアウトなし) |
| Grid: 10% change text | 10% のセルのラベルを毎フレーム変更 (桁数は同じ) |
| Grid: 10 hit tests | 変化なし。毎フレーム 10 回のヒットテスト |
| List | スクロールビューの中の 500 行 (仮想化なし)。行は角丸のパネル、丸いアイコン、タイトル、値 |
| List: scroll | 毎フレームスクロール |
| List: 10% relayout | 10% の行のタイトルを毎フレーム 1 行と 2 行で切り替え、レイアウトをやり直させる |
各システムでは、見た目を揃えたうえで、それぞれの通常の方法で画面を組んでいます。
| YAUI | uGUI + TextMeshPro | UI Toolkit | |
|---|---|---|---|
| Grid | 折り返しのある flex の行 | アンカー (Layout Group なし。uGUI で最も速い方法) | 折り返しのある flex の行 |
| List | YauiScrollView の中の flex の列 | ScrollRect、RectMask2D、Vertical / Horizontal Layout Group | ScrollView |
| 角丸 | ボックスのスタイル | 9 スライスのスプライト (アトラスのように 1 枚のテクスチャから) | border-radius |
| テキスト | YauiText | TextMeshPro | Label |
| 最適化 | アイコンとラベルはレイキャストの対象外 | 定番のもの: 変化するセルを子 Canvas に分離、アイコンとラベルはレイキャストの対象外、isTextObjectScaleStatic | 変化するセルに Usage Hints、アイコンとラベルはピッキングの対象外 |
| ヒットテスト | EventSystem.RaycastAll | EventSystem.RaycastAll | IPanel.Pick |
結果
CPU
フレームあたりのメインスレッドの時間 (ミリ秒、表示の待ちを除く)。空のシーンからの増分を括弧内に示します。
| シナリオ | YAUI | uGUI + TextMeshPro | UI Toolkit |
|---|---|---|---|
| 空のシーン | 2.54 | 2.54 | 2.54 |
| Grid: no changes | 2.59 (+0.05) | 3.23 (+0.69) | 3.38 (+0.84) |
| Grid: 10% change color | 3.04 (+0.50) | 5.49 (+2.95) | 3.77 (+1.22) |
| Grid: 10% move | 2.97 (+0.43) | 4.29 (+1.75) | 4.23 (+1.69) |
| Grid: 10% change text | 7.52 (+4.98) | 7.39 (+4.85) | 15.63 (+13.09) |
| Grid: 10 hit tests | 2.78 (+0.24) | 8.40 (+5.86) | 5.44 (+2.90) |
| List: scroll | 3.18 (+0.64) | 7.26 (+4.72) | 3.64 (+1.10) |
| List: 10% relayout | 14.25 (+11.71) | 81.17 (+78.63) | 9.44 (+6.90) |
空のシーンをわずかに下回る値は誤差の範囲なので、±0 と表記しています。
描画スレッドはどのシナリオでも 0.5〜1.8 ms で、システム間の差は小さくなっています。
GPU
GPU は負荷に応じてクロックを変えるため、異なるシーンの GPU 時間はそのままでは比べられません。ここでは、重い全画面のパスで GPU を最高クロックに保ち、そのパスだけのときとの差を UI のコストとしています。
| シナリオ | YAUI | uGUI + TextMeshPro | UI Toolkit |
|---|---|---|---|
| Grid | +2.98 | +2.98 | +8.67 |
| List | +2.22 | +1.43 | +3.02 |
通常のフレームのようにクロックが低いときは、同じ処理にもっと時間がかかります。
注意点
- テキスト: テキストの変更にかかる時間は実行ごとにばらつきます (YAUI の合計で 3.8〜7.5 ms。今回の中央値は 7.5 ms)。
- レイアウト: YAUI はメインスレッドでレイアウトのジョブを待ちます。リストの行は高さが内容で決まるためレイアウトの境界にならず、リスト全体がレイアウトし直されます。
- 「List: 10% relayout」では、2 行でも行の最小の高さに収まるため、行の高さはほぼ変わりません。
- UI Toolkit のヒットテスト (
Pick) は最前面の要素だけを返します。ほかの 2 つは、その点にあるすべての要素を返します。 - 結果は 1 台の端末のものです。端末、グラフィックス API、内容によって変わります。
ベンチマークの実行
- TextMeshPro の Essential Resources をインポートします (Window > TextMeshPro > Import TMP Essential Resources)。
Assets/Benchmarks/Comparison/ComparisonBenchmark.unityだけを含めて端末向けにビルドします。Development Build では、プロファイラのマーカーによる内訳も記録されます。- アプリは全シナリオを実行し (約 25 分)、結果を表示して、CSV として
Application.persistentDataPathに書き出します。 Assets/Benchmarks/Tools~/chart.pyは CSV から表を出力し、グラフを描きます。
このページの計測結果の生データは Assets/Benchmarks/Results~ にあります。