구조체의 크기는, 구조체 내부의 변수들의 정렬에 의해 가변적일 수 있다.
다음의 메모리 사이즈와 메모리 배열을 살펴보자.
public struct TestA
{
public int itemA;
public bool itemB;
public int itemC;
public bool itemD;
}
public struct TestB
{
public int itemA;
public int itemC;
public bool itemB;
public bool itemD;
}
결과 도출 코드
private void Start()
{
// TestA의 메모리 체크
Debug.Log($"UnsafeUtility.AlignOf<TestA>() :: {UnsafeUtility.AlignOf<TestA>()}");
Debug.Log($"UnsafeUtility.SizeOf<TestA>() :: {UnsafeUtility.SizeOf<TestA>()}");
// TestB의 메모리 체크
Debug.Log($"UnsafeUtility.AlignOf<TestB>() :: {UnsafeUtility.AlignOf<TestB>()}");
Debug.Log($"UnsafeUtility.SizeOf<TestB>() :: {UnsafeUtility.SizeOf<TestB>()}");
}
결과
TestA 구조체
Align : 4 byte
Size : 16 byte
TestB 구조체
Align : 4 byte
Size : 12 byte
무려 25%의 효과를 얻을 수 있다.
( 이에 대한 자세한 설명은 출처를 참고하였다. )
우선 구조체 TestA의 정렬은
1 itemA | itemA | itemA | itemA
2 itemB | - | - | -
3 itemC | itemC | itemC | itemC
4 itemD | - | - | -
와 같고
TestB의 메모리 정렬은
1 itemA | itemA | itemA | itemA
2 itemC | itemC | itemC | itemC
3 itemB | itemD | - | -
와 같다.
다음의 메모리 사이즈와 메모리 배열을 살펴보자.
// 중첩용 구조체
public struct TestA
{
public bool a;
public long b;
public bool c;
}
// 중첩된 구조체
public struct TestB
{
public TestA a;
public bool d;
public int e;
}
// 중첩 해제후 무작위 정렬한 구조체
public struct TestC
{
public bool a;
public long b;
public bool c;
public bool d;
public int e;
}
// 중첩 해제후 정렬한 구조체
public struct TestD
{
public long b;
public bool a;
public bool c;
public bool d;
public int e;
}
결과
TestA 구조체
Align : 8 byte
Size : 24 byte | 정렬시 Size : 16byte
TestB 구조체
Align : 8 byte
Size : 32 byte
TestC 구조체 : TestB 구조체 대비 25% 절감
Align : 8 byte
Size : 24 byte
TestD 구조체 : TestB 구조체 대비 50% 절감
Align : 8 byte
Size : 16 byte
메모리 배열
1 a | - | - | - | - | - | - | -
2 b | b | b | b | b | b | b | b
3 c | - | - | - | - | - | - | -
TestB , C , D는 다음과 같다.
1 a | - | - | - | - | - | - | -
2 b | b | b | b | b | b | b | b
3 c | - | - | - | - | - | - | -
4 e | e | e | e | d | - | - | -
1 a | - | - | - | - | - | - | -
2 b | b | b | b | b | b | b | b
3 e | e | e | e | c | d | - | -
1 b | b | b | b | b | b | b | b
2 e | e | e | e | c | d | a | -
public enum TestEnum
{
itemA,
itemB,
...
}
만약 이런 식으로 선언한다면, 이 enum은 int 형을 따라간다. 고로 4byte의 크기를 지니는데, ushort나 byte로 정의하면 2byte 내지 1byte로 처리가 가능하다.
public enum TestEnum : byte
{
itemA,
itemB,
...
}
public struct EmptyStruct
{
}
public struct EnumeratorStruct
{
public IEnumerator routine;
}
Align : 1byte
Size : 1byte
Align : 8byte
Size : 8byte
public struct NativeArrayStruct
{
public NativeArray<T> array;
}
public struct NativeListStruct
{
public NativeList<T> list;
}
public struct NativeQueueStruct
{
public NativeList<T> list;
}
public struct NativeListStruct
{
public NativeList<T> list;
}
public struct NativeHashMapStruct
{
public NativeHasMap<K,V> map;
}
public struct NativeTextStruct
{
public NativeText text;
}
public struct NativeParallelHashMap
{
public NativeParallelHashMap<K,V> parallelMap;
}
public struct BlobString
{
public BlobString str;
}
Align : 8byte
Size : 48byte
Align : 8byte
Size : 32byte
Align : 8byte
Size : 40byte
Align : 8byte
Size : 24byte
Align : 8byte
Size : 24byte
Align : 8byte
Size : 32byte
Align : 4byte
Size : 8byte