1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】WebGL上でAllocateがどのぐらい負荷になるのかを計測した

Last updated at Posted at 2025-12-07

はじめに

スクリーンショット 2025-12-07 21.33.15.png
Profireでよく見かけるGC.Alloc

GCのヒープ領域を確保していることをしてしていて、このヒープ領域がいっぱいになるとC#のGCが発動する
このGCは、メインスレッド上で行われ、他の処理を止めてしまうことでパフォーマンスへ影響を与える

WebGLでは非常に限られたヒープ領域でやりくりするため、このGCによるパフォーマンス低下が顕著に現れる
そこで今回は、Allocateによってどのぐらいパフォーマンスへ影響が出るか計測してみる

実験内容

以下のようなスクリプトを用意し、フレームあたりどのぐらいAllocateするかをUIから設定できるようにする

FpsMesure.cs
FpsMesure.cs
using TMPro;
using UnityEngine;

public class FpsMesurere : MonoBehaviour
{
    [SerializeField] private TMP_Text fps1FrameText;
    [SerializeField] private TMP_Text fps1SecondText;
    [SerializeField] private TMP_Text fps5SecondText;

    private int frameCount1Sec;
    private int frameCount5Sec;
    private float elapsedTime1Sec;
    private float elapsedTime5Sec;
    private float fps1Sec;
    private float fps5Sec;

    void Update()
    {
        var deltaTime = Time.deltaTime;

        // 1フレームのFPS
        var fps1Frame = 1.0f / deltaTime;
        fps1FrameText.text = $"1Frame FPS: {fps1Frame:F1} FPS";

        // 1秒平均
        frameCount1Sec++;
        elapsedTime1Sec += deltaTime;
        if (elapsedTime1Sec >= 1.0f)
        {
            fps1Sec = frameCount1Sec / elapsedTime1Sec;
            frameCount1Sec = 0;
            elapsedTime1Sec = 0f;
        }
        fps1SecondText.text = $"1Sec Average FPS: {fps1Sec:F1} FPS";

        // 5秒平均
        frameCount5Sec++;
        elapsedTime5Sec += deltaTime;
        if (elapsedTime5Sec >= 5.0f)
        {
            fps5Sec = frameCount5Sec / elapsedTime5Sec;
            frameCount5Sec = 0;
            elapsedTime5Sec = 0f;
        }
        fps5SecondText.text = $"5Sec Average FPS: {fps5Sec:F1} FPS";
    }
}
Allocator
Allocator.cs
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class Allocator : MonoBehaviour
{
    [SerializeField] TMP_Text perFrameAllocateNumText;

    [SerializeField] Button PerFrame0AllocateBtn;
    [SerializeField] Button PerFrame100AllocateBtn;
    [SerializeField] Button PerFrame1000AllocateBtn;
    [SerializeField] Button PerFrame10000AllocateBtn;
    [SerializeField] Button PerFrame30000AllocateBtn;
    [SerializeField] Button PerFrame50000AllocateBtn;

    int perFrameAllocateNum = 0;

    void Start()
    {
        PerFrame0AllocateBtn.onClick.AddListener(() => SetAllocateNum(0));
        PerFrame100AllocateBtn.onClick.AddListener(() => SetAllocateNum(100));
        PerFrame1000AllocateBtn.onClick.AddListener(() => SetAllocateNum(1000));
        PerFrame10000AllocateBtn.onClick.AddListener(() => SetAllocateNum(10000));
        PerFrame30000AllocateBtn.onClick.AddListener(() => SetAllocateNum(30000));
        PerFrame50000AllocateBtn.onClick.AddListener(() => SetAllocateNum(50000));

        UpdateText();
    }

    void SetAllocateNum(int num)
    {
        perFrameAllocateNum = num;
        UpdateText();
    }

    void UpdateText()
    {
        perFrameAllocateNumText.text = $"Allocate/frame: {perFrameAllocateNum}";
    }

    void Update()
    {
        for (int i = 0; i < perFrameAllocateNum; i++)
        {
            Allocate();
        }
    }

    void Allocate()
    {
        // 1KBのバイト配列をアロケート(GCに負荷をかける)
        byte[] data = new byte[1024];
    }
}

スクリーンショット 2025-12-07 22.13.19.png

これをWebGLでBuild and Runして計測を行う

環境

Unity 6000.3.0.f1
MacBook Pro(Apple M3 Pro, 18GB)
Google Chrome(142.0.7444.176)

Target Frame Time 60FPS

計測結果

Allocate数を変更後、30秒後の5Sec FPSの値を計測結果とした

Allocate / frame FPS
0 60.0
100 60.0
1000 60.0
10000 42.1
30000 22.7
50000 15.1
  • 1000Allocate/Frame程度であればパフォーマンスへ影響がない
  • 10000Allocate/Frameを超えたところからパフォーマンスへ影響がある
  • 50000Allocate/Frameを超えるとほぼプレイ不可

終わりに

new()や、一時配列、ToString()など、よく使うメソッドの中にAllocateが潜んでいる
これからは意識的にAllocate数(量)を減らしていきたい

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?