本記事は サムザップ Advent Calendar 2025 の 25日目 の記事です 🎄
はじめに:パフォチューってなに?美味しいの?🍰
パフォーマンスチューニング?
正直、「できる人がやるやつ」だと思ってました。
自分は Unity のクライアントエンジニアで、
機能開発や不具合修正はそれなりにやってきましたが、
- Profiler は開いたことあるだけ
- 数字を見ても「で、何を直すの?」状態
- パフォーマンス改善は 完全に未経験
そんな自分が最近知ったのが、
パフォーマンス改善には
静的解析(コードを見る) と
動的解析(実行時を見る) の2つがある
という事実。
いきなり Profiler とにらめっこするのはハードルが高い。
じゃあまずは 静的解析からやってみよう。
そして思いました。
AIがいる今なら、
パフォチュー赤ちゃんでもいけるんじゃない?
というわけで、
AIと一緒に Unity 向けの静的解析ツールを育ててみることにしました。
静的解析、AIに頼ってみた(Cursorさん、お願いします🙏)
最初に考えたのはこんな感じです。
- 手でコードレビュー?
→ 無理。量が多すぎる - 既存の静的解析ツール?
→ 厳しすぎる or Unityの文脈を見てくれない
そこで頼ったのが Cursor。
Cursorさんにお願いしたことはシンプルで、
- Update / LateUpdate / FixedUpdate を見る
- 毎フレーム重い処理を検知する
- ただし うるさすぎないことが最重要
…だったのですが。
でも最初は地獄だった(誤検知がウザすぎる😇)
最初にできたツールは、
とにかく正義感が強い。
例えば、こんな警告が出ました。
{
"rule": "UPD_TRS_LOOP",
"severity": "S",
"message": "Loop contains heavy operation: TransformPoint. This is executed every frame."
}
一見すると、正しそうです。
でも対象コードを見ると…
private void LateUpdate()
{
if (_commonSpineController == null) return;
// Bone追従オブジェクトの位置更新
// SpineMotionMixerBehaviourでのボーン更新と1フレずれないようにLateUpdateで更新している
foreach (var (boneFollower, targetBone) in _boneFollowers)
{
var boneWorldPosition =
_commonSpineController.transform.TransformPoint(
new Vector3(targetBone.WorldX, targetBone.WorldY, 0));
boneFollower.position = boneWorldPosition;
}
// Bone初期位置追従オブジェクトの位置更新
foreach (var boneInitialFollower in _boneInitialFollowers)
{
var boneWorldInitialPosition =
_commonSpineController.transform.TransformPoint(
boneInitialFollower.initialPosition);
boneInitialFollower.boneFollower.position = boneWorldInitialPosition;
}
}
「意図して書いたコード」に怒られる問題
これ、どう見ても 意図的 な処理です。
- Spine のボーン追従
- フレームずれを防ぐために
LateUpdate -
TransformPointを使うのも分かった上でやっている
それなのに、毎回 severity: S で怒られる。
正直な感想はこれでした。
これ、実プロジェクトで使ったら
「うるさいだけのツール」になるな…
発想を変えた:「怒られないツール」を作ろう
ここで方針を切り替えました。
AIに 「全部判断させる」 のをやめて、
人間の意図を前提にする設計 にします。
具体的には:
- 意図的な処理はコメントで宣言できるようにする
-
Update内でも- 早期
returnガードがある - 明らかに軽いループ
- Editor 専用コード
はseverityを下げる or スキップ
- 早期
- 「完璧な検知」よりも
レビューで納得できる精度を目指す
Cursorさんとコンテキストを詰めながら、
- 「それは怒らなくていい」
- 「これはさすがに重い」
を少しずつ教えていきました。
改善後の具体例:「これは確かに指摘してほしい」
誤検知が減った一方で、
「これはちゃんと怒られていい」ケースも残るようになりました。
たとえば、次のような検知です。
{
"rule": "UPD_TRS_LOOP",
"severity": "S",
"file": "Assets/Project/Battle2/Scripts/Main/View/Unit/UnitEffect.cs",
"method": "LateUpdate",
"line": 116,
"loop_line": 116,
"loop_type": "foreach",
"message": "Loop contains heavy operation: TransformPoint. This is executed every frame.",
"snippet": "foreach (var boneInitialFollower in _boneInitialFollowers)\n { // TransformPoint"
}
対象になったコードはこちらです。
private void LateUpdate()
{
if (_commonSpineController == null) return;
// Bone追従オブジェクトの位置更新
// SpineMotionMixerBehaviourでのボーン更新と1フレずれないようにLateUpdateで更新している
foreach (var (boneFollower, targetBone) in _boneFollowers)
{
var boneWorldPosition =
_commonSpineController.transform.TransformPoint(
new Vector3(targetBone.WorldX, targetBone.WorldY, 0));
boneFollower.position = boneWorldPosition;
}
// Bone初期位置追従オブジェクトの位置更新
foreach (var boneInitialFollower in _boneInitialFollowers)
{
var boneWorldInitialPosition =
_commonSpineController.transform.TransformPoint(
boneInitialFollower.initialPosition);
boneInitialFollower.boneFollower.position = boneWorldInitialPosition;
}
}
ここが 「あー、これは確かに指摘されていいな」 と思えたポイントです。
- 処理自体は 意図的
-
LateUpdateを使っている理由も明確 - ただし
- 2つのループ
- 毎フレーム
-
TransformPointを複数回実行
しているのは事実
つまりこれは、
「設計として正しいけど、
本当にこの頻度・この実装で最適かは
一度立ち止まって考えたい」
タイプのコード。
即バグではないけど、
パフォーマンス改善の余地はある。
Severity: S が付くのも、
今ならちゃんと納得できます。
この時点で初めて、
- 「怒られた」ではなく
- 「レビューされた」
という感覚になりました。
改善後:ちゃんと“会話できる”結果になった
最終的に出てきた結果はこんな感じです。
"stats": {
"by_severity": {
"S": 3,
"A": 7,
"C": 5
}
}
- 意図的な処理 → 出ない or 軽め(C)
- 本当に危ない処理 → Sで出る
- 全体量も 「ちゃんと読める数」
これなら、
- CIで落とさなくてもいい
- レビューで「ここどうする?」と会話できる
- パフォーマンス未経験者でも怖くない
「怒られない静的解析ツール」 になりました。
ここまでできた(パフォチュー初心者でも)
自分は、
- パフォーマンス未経験
- Profilerも怖い
- パフォチューって何?状態
それでも、
- 実プロジェクトで使える静的解析ツールを作れた
- 誤検知を減らし、意図を伝えられる設計にできた
- AIを「魔法」ではなく「相棒」として使えた
というところまでは、ちゃんと来れました。
次は動的解析(AI × Unity Profiler)
この記事は 静的解析編 です。
次にやりたいのは、
- Unity Profiler の結果をAIに読ませる
- 「どこが重いか」を言語化させる
- 静的解析と組み合わせて改善ポイントを絞る
まだ試行中ですが、
これもまた パフォチュー初心者向けのやり方 で進める予定です。
おわりに
パフォーマンスチューニングは、
「できる人だけのもの」じゃありませんでした。
AIがいる今なら、
- 分からなくても
- 怖くても
- 少しずつ教えながら
一緒に前に進める。
パフォチュー、
意外と美味しいかもしれません。🍰