Skip to content
Back to skills

Performance

ASecurity

Advise on Unity performance red flags

  • 17 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 4, 2026
developmentgoexpressrailsperformancedocumentation

Security analysis

A100/100

Scanned September 4, 2026

npx -y skills add gabrielmoreira/agent-skills-mirror --skill performance --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Performance?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Performance
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/gabrielmoreira-performance/badge)](https://www.skillsdirectory.com/skills/gabrielmoreira-performance)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: unity-performance
description: Advise on Unity performance red flags
---

> **Before calling any skill in this module:** if you are about to call a skill with parameters guessed from its name or description, STOP — read this file (or fetch its schema via `GET /skills/recommend?includeSchema=true`) first. If you already have the parameter definitions from recommend/schema, you may proceed straight to dryRun.

## Triggers
- Reviewing performance
- Diagnosing frame drops
- Reducing allocations
- Planning pooling/optimization
- 做性能审查、诊断掉帧或卡顿、减少内存分配、规划对象池/优化

# Unity Performance Red Flags

Use this skill for a high-signal review of likely Unity performance issues. Focus on red flags, not speculative micro-optimizations.

## Check For

- Too many unrelated `Update` / `LateUpdate` / `FixedUpdate` loops
- Repeated `Find`, `GetComponent`, `Camera.main`, or tag lookups in hot paths
- Frequent `Instantiate` / `Destroy` suitable for pooling
- Avoidable per-frame allocations:
  - LINQ
  - string formatting
  - closures
  - boxing
- Reflection in runtime hot paths
- Expensive editor-only helpers leaking into runtime code
- Physics, animation, or UI updates happening at the wrong cadence

## Hidden Costs: Possibility ≠ Actuality

Three counter-intuitive traps where what seems "free" is actually expensive. Each cost is paid for *possibility* of work, not for work actually performed — which is why profilers rarely catch them directly.

### Write permission costs, even without writing
A component whose `Update` *can* mutate `transform.position` pays the cost whether the branch runs or not: dirty-flag and serialization systems treat write permission as a reason to poll every frame. Similarly, a `[SerializeField]` field that is never modified at runtime still sits on the serialization path. The fix is to **remove the permission**, not tighten the branch — split the rarely-needed writer into its own component and `AddComponent` only when needed. *Source: `NetcodeSamples/HelloNetcode/2_Intermediate/07_Optimization/Optimization.md` — "a system with the possibility of writing to a component, regardless of whether it writes to it or not, will always have to be serialized".*

### Sequential seeds produce correlated random streams
Seeding N RNG instances with `baseSeed + i` gives N *similar* streams — patrol paths line up, spawn jitter clumps, loot rolls cluster. Hash the index before seeding:
```csharp
// Wrong — N correlated streams
for (int i = 0; i < N; i++) rngs[i] = new System.Random(baseSeed + i);

// Correct — hash decorrelates adjacent seeds
for (int i = 0; i < N; i++)
    rngs[i] = new System.Random((int)((uint)baseSeed * 2654435761u ^ (uint)i));
```
`Unity.Mathematics.Random.CreateFromIndex(i)` applies this internally and is preferred when the math package is available. *Source: `Dots101/Entities101/Assets/HelloCube/3. Prefabs/SpawnSystem.cs:37-39` and its comment.*

### Logging fires in release builds by default
`Debug.Log` is **not** stripped in Player builds; only methods marked `[Conditional("UNITY_EDITOR")]` (such as `Debug.DrawLine`) have their arguments elided at the call site. That means a log line with interpolation or helper calls runs every frame in shipped games:
```csharp
// Wrong — GetPlayerInfo() and string interpolation execute in release
Debug.Log($"Player {GetPlayerInfo()} at {Time.time}");

// Better — guard the whole expression
if (Debug.isDebugBuild) Debug.Log($"Player {GetPlayerInfo()} at {Time.time}");
```
The same principle as the "possibility write" rule above — the runtime pays for the *possibility* of work, not only for the work.

## Output Format

- Confirmed red flags
- Likely red flags
- Changes worth doing now
- Changes not worth doing now
- Expected gain category: clarity / frame time / GC / scalability

## Guardrails

> **Mode**: Documentation only — no REST skills to gate; load freely under any operating mode (Approval / Auto / Bypass).

- Do not recommend large refactors without a meaningful hotspot.
- Do not replace simple code with unreadable “optimized” code unless the hot path is real.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…