【Unity】ZLinqを使う
概要
高パフォーマンスでゼロアロケーションなZLinqがリリースされました。
従来のLinqは、パフォーマンス(処理速度)が悪く、GCが発生してしまう問題がありました。
特にUnityで使う場合にはパフォーマンスの問題は顕著に発生してしまうため、「Update内でLinq使用禁止」というコーディング規約が生まれてしまうほどでした。
今回はそれらの問題が解決されたZLinqのUnityでの導入方法とパフォーマンス比較を紹介します。
導入
まずZLinqを入れるためにNuGetForUnityをインストールします。
Window->Package Managerを開き、左上のInstall package from git URL...
を選択します。
そして、下記URLを入力してInstall
をクリックします
https://github.com/GlitchEnzo/NuGetForUnity.git?path=/src/NuGetForUnity
NuGetForUnityがインストール出来たらツールバーにNuGet
が出てくるので
Manage NuGet Packages
を開きます。
検索ボックスにZLinq
を検索し、チェックを入れてInstallします。
最後に再びPackage ManagerからInstall package from git URL...
を開き、ZLinqのURLを入力します
https://github.com/Cysharp/ZLinq.git?path=src/ZLinq.Unity/Assets/ZLinq.Unity
これでZLinqのインストールは完了です。
使ってみる
簡単な使い方は下記のとおりです。
従来のLinqから.AsValueEnumerable()
を追加すればそのまま移行することができます。
using UnityEngine;
using ZLinq; //usingを追加
public class ZLinqSample : MonoBehaviour
{
void Start()
{
var numbers = new[] { 1, 2, 3, 4, 5 };
var average = numbers
.AsValueEnumerable() //配列に対してはこれを追加
.Average();
Debug.Log($"Average: {average}");
}
}
パフォーマンス比較
Average,Sum,Whereで比較をしてみました
比較用のテストコード
using UnityEngine;
using ZLinq;
using System.Linq;
public class LinqVS : MonoBehaviour
{
float[] testArray = new float[10000];
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
for(var i=0;i<testArray.Length;i++)
{
testArray[i] = Random.Range(0f, 100f);
}
}
// Update is called once per frame
void Update()
{
DoAverage();
DoSum();
DoSelect();
ZLinqAverage();
ZLinqSum();
ZLinqSelect();
}
void DoAverage()
{
var agerage = testArray.Average();
}
void DoSum()
{
var sum = testArray.Sum();
}
void DoSelect()
{
var select = testArray.Where(x => x > 50f);
}
void ZLinqAverage()
{
var agerage = testArray.AsValueEnumerable().Average();
}
void ZLinqSum()
{
var sum = testArray.AsValueEnumerable().Sum();
}
void ZLinqSelect()
{
var select = testArray.AsValueEnumerable().Where(x => x > 50f);
}
}
using | 関数 | 実行時間[ms] | GC |
---|---|---|---|
System.Linq | Average() | 1.72 | 32B |
ZLinq | Average() | 0.57 | 0B |
System.Linq | Sum() | 1.68 | 32B |
ZLinq | Sum() | 0.56 | 0B |
System.Linq | Where | 0.00 | 48B |
ZLinq | Where | 0.00 | 0B |
いずれの関数でも実行時間が短くGCの発生が抑えられています
まとめ
本記事ではZLinqの導入から使い方、パフォーマンスの比較まで説明しました。
現在使っているLinqのコードを差し替えるだけでパフォーマンスの向上ができるので、導入する価値は十分にあると思います。
是非検討してみてください
Discussion