Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 로케트
- callbyvalue
- C#
- 유니티
- 인터페이스
- Quaternion
- 깃허브
- 게임
- ExtensionMethod
- AR세팅
- 1인개발
- 리듬게임에디터
- Unity
- callbyreference
- AR게임
- 짐벌락
- AR Foundation
- 게임제작
- 리듬게임
- Euler
- 델리게이트
- raycast
- 병맛게임
- ARProgect
- 게임개발
- 확장메서드
- 레이캐스트
- github
- ar
- 소규모프로젝트
Archives
- Today
- Total
Ssssong += Dev
[C#/유니티] (최적화) Foreach 루프 본문
유니티 5.5버전 이전까지 Foreach문을 사용하면 가비지가 생기는 현상이 있었다.
하지만 이후 버전에서는 개선되었는데, 이 과정이 어땠는지 적힌 좋은 글이 있다.
List와 Dictionary와 같은 IEnumerable을 상속받는 컬렉션은 foreach문으로 탐색할 경우 C# 컴파일러에서
다음과 같이 동작한다.
using (List<int>.Enumerator enumerator = list.GetEnumerator())
{
while(enumerator.MoveNext())
{
int current = enumerator.get_Current();
}
}
여기서 Enumerator는 IDisposable을 상속받는 struct 타입이다.
public struct Enumerator : IEnumerator<T>, IEnumerator, IDisposable
{
public T Current { get; }
public void Dispose();
public bool MoveNext();
}
어? using...? IDisposable...? 그렇다면 using 종료 후 Dispose()가 실행된다는 것이다.
참조한 글에 따르면 저 코드는 이런 의미와 같다고 한다.
Enumerator enumerator = list.GetEnumerator();
try
{
while(enumerator.MoveNext())
{
int current = enumerator.Current;
}
}
finally
{
var disposable = (System.IDisposable)enumerator;
disposable.Dispose();
}
이 때, var disposable = (System.IDisposable)enumerator; 때문에
struct, 즉 Value-Type인 enumerator가 박싱되는 것 때문에 생긴 가비지였다고 한다.
(인터페이스 타입으로 캐스팅 시 죄다 Reference-type으로 처리되는 것 때문)
그런데 업데이트된 컴파일러에서는
constrained라는 instruction을 통해 (IL 언어라 잘 모르겠다...) enumerator의 포인터를 넘겨버리는 것으로
Value-Type이고 Reference-Type이고 자시고 간에 callvirt를 하는 데 문제없게 만들었다. <<여기 좀 모르겠지만...
따라서 박싱이 일어나지 않게 되었고
최신 컴파일러를 사용하는 유니티에서는 foreach 문 사용 시에 더이상 내부적으로 가비지를 만들지 않게 되었다.