はじめに
「StructLinq」を Unity プロジェクトに導入することで
ゼロアロケーションの LINQ を使用できるようになります
検証環境
- Unity 2021.2.7f1
- Windows IL2CPP ビルド
検証結果
using System; using System.Linq; using StructLinq; using UnityEngine; using UnityEngine.Profiling; public sealed class Example : MonoBehaviour { private readonly CharacterMaster[] m_characterMasters = Enumerable .Range( 0, 1_000_000 ) .Select( x => new CharacterMaster( x ) ) .ToArray(); private void Update() { if ( !Input.GetKeyDown( KeyCode.Space ) && !Input.GetKeyDown( KeyCode.Escape ) ) { return; } using ( new CustomSamplerScope( "#### Linq" ) ) { m_characterMasters .Where( x => x.Id % 2 == 1 ) .Select( x => x.Id * 2 ) ; } using ( new CustomSamplerScope( "#### Struct Linq With Delegate" ) ) { m_characterMasters .ToStructEnumerable() .Where( x => x.Id % 2 == 1 ) .Select( x => x.Id * 2 ) ; } using ( new CustomSamplerScope( "#### Struct Linq With Delegate Zero Alloc" ) ) { m_characterMasters .ToStructEnumerable() .Where( x => x.Id % 2 == 1, x => x ) .Select( x => x.Id * 2, x => x ) ; } using ( new CustomSamplerScope( "#### Struct Linq Zero Alloc" ) ) { var where = new WherePredicate(); var select = new SelectPredicate(); m_characterMasters .ToStructEnumerable() .Where( ref where, x => x ) .Select( ref select, x => x, x => x ) ; } } private struct WherePredicate : IFunction<CharacterMaster, bool> { public bool Eval( CharacterMaster element ) { return element.Id % 2 == 1; } } private struct SelectPredicate : IFunction<CharacterMaster, int> { public int Eval( CharacterMaster element ) { return element.Id * 2; } } private readonly struct CustomSamplerScope : IDisposable { private readonly CustomSampler m_customSampler; public CustomSamplerScope( string name ) { m_customSampler = CustomSampler.Create( name ); m_customSampler.Begin(); } public void Dispose() { m_customSampler.End(); } } private sealed class CharacterMaster { public int Id { get; } public CharacterMaster( int id ) { Id = id; } } }