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?

c# 一時的な配列に関する個人的な試行錯誤

Last updated at Posted at 2025-05-06

目的

一時的な配列を受け渡しするのに、普通の配列やListを使うとGCゴミが発生します。
例えばゲームマネージャーからアクティブなプレイヤーを取得するのを考えます。

public List<Player> GetActivePlayers()
{
    List<Player> list = new(); //将来的にごみになる
    foreach(var player in players){
        if(player.isActive)list.Add(player);
    }
    return list;
}

stack上で処理が完結すれば、ゴミが出ないのではないかというのがこの試行錯誤の原点です。

0. stackallocで確保したSpanを、なんやかんやして出力する(ダメ)

普通にエラーになります

public Span<int> CreateData()
{
    return stackalloc int[]{0,1,2,3};// エラー
}

1. 構造体を示した一時的なSpanを受け渡す(ダメ)

構造体をSpanとして扱えるようなレイアウトで定義して、Spanを出力する。
構造体が関数を抜けた瞬間解放されるので、Spanにアクセスできるけどメモリリークになります。

using System;
using System.Runtime.InteropServices;
class Program
{
    public struct A
    {
        int n0, n1, n2, n3, n4;
        public Span<int> AsSpan() => MemoryMarshal.CreateSpan(ref n0, 5);
    }
    public static Span<int> Create()
    {
        A a = new();
        var span = a.AsSpan();
        span[0] = 0;
        span[1] = 1;
        span[2] = 2;
        span[3] = 3;
        span[4] = 4;
        Display(span);// 0 1 2 3 4
        return span;
    }
    public static void Display(Span<int> span)
    {
        foreach(ref var num in span) Console.WriteLine(num);
    }
    static void Main()
    {
        Display(Create()); // 無茶苦茶な値になる
    }
}

2. 配列っぽい構造体を受け渡す

  1. で出力するのをSpanではなく配列構造体そのものにします。
    しかし、構造体のコピーの仕様により、配列構造体の大きさによってコピーのコストが発生します。

3. UnityのNativeArray(Allocator.Temp)的な処理をする

UnityのNativeArrayはGCが発生しない方法で、いい感じに管理されてるみたいです。
で、Allocator.Tempを指定した場合は、解放処理が一括で行われて処理負荷が全然ないようです。
これとc#のArrayPoolの内容を斜め読みした知識をミックスして、独自の一時配列を作ってみようと思います。

できたのがこちら

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?