コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】LINQ の拡張メソッドを自作して GC Alloc を減らす方法

概要

using System.Linq;
using UnityEngine;

public class Example : MonoBehaviour
{
    private static string[] m_list =
    {
        "フシギダネ",
        "フシギソウ",
        "フシギバナ",
    };

    private void Update()
    {
        var name = "ピカチュウ";

        var result = m_list.Where( c => c == name );
    }
}

通常の LINQ をそのまま使用すると

f:id:baba_s:20191224120913p:plain

184 B の GC Alloc が発生しますが

using System;
using System.Collections.Generic;
using UnityEngine;

public class Example : MonoBehaviour
{
    private static string[] m_list =
    {
        "フシギダネ",
        "フシギソウ",
        "フシギバナ",
    };

    private void Update()
    {
        var name = "ピカチュウ";

        var result = m_list.WhereNotAlloc( ( c, value ) => c == value, name );
    }
}

public static class EnumerableExt
{
    public static IEnumerable<T> WhereNotAlloc<T, TValue>
    (
        this IEnumerable<T>   self,
        Func<T, TValue, bool> predicate,
        TValue                value
    )
    {
        foreach ( var n in self )
        {
            if ( predicate( n, value ) )
            {
                yield return n;
            }
        }
    }
}

上記のように変数キャプチャを回避する拡張メソッドを自作して使用すると

f:id:baba_s:20191224120957p:plain

GC Alloc を 96 B に抑えることができます

参考サイト様

https://www.slideshare.net/xin9le/dotnetperformancetips-170268354

関連記事