2010-03-15 4 views
15

XNA 및 C#을 사용하여 게임을 개발 중이며 new struct() 코드를 각 프레임마다 호출하지 않으려 고 시도했습니다. GC를 괴롭힐 것으로 생각했습니다. "하지만 기다려라,"나는 구조체가 가치 유형이라고 스스로에게 말했다 .GC는 호출되지 않아야한다. " 글쎄, 그래서 내가 여기서 물어 보는거야.값 유형을 만들면 어떻게됩니까?

나는 값 유형에 어떤 변화가 있는지 매우 모호합니다. 함수 호출 내에서 새로운 구조체를 생성하면 스택에 구조체가 생성됩니까? 단순히 밀고 당겨서 성능이 떨어지지 않을까요? 또한 한 번의 호출로 많은 인스턴스를 생성해야한다면 메모리 제한이나 성능에 영향을 미칠 수 있습니까?

테이크는, 예를 들어,이 코드 :

spriteBatch.Draw(tex, new Rectangle(x, y, width, height), Color.White); 

사각형이 경우는 구조체이다. 새로운 Rectangle이 만들어지면 어떻게됩니까? 그 줄을 여러 번 (수천 번) 반복해야한다는 의미는 무엇입니까? 이 Rectangle이 만들어지고, Draw 메서드로 전송 된 복사본이 삭제 되었습니까? (동일한 함수에서 더 많은 Draw가 그 방식으로 호출되는 것을 의미하지 않습니다.)

P. 나는 이것이 성숙한 최적화일지도 모른다는 것을 알고 있지만, 나는 대체로 궁금해서 무엇이 일어나고 있는지 더 잘 이해하고 싶다.

답변

4

새로운 구조체가 생성되면 내용은 지정한 위치에 바로 입력됩니다. 메소드 변수 인 경우 스택에 저장됩니다. 클래스 변수에 할당되면 클래스 인스턴스가 힙에 있음을 알 수 있습니다.

구조체 변수를 복사 할 때 (또는 함수에 전달한 경우) 구조체를 구성하는 바이트가 모두 스택의 올바른 위치 또는 클래스 내부로 복사됩니다 (참조 유형 인스턴스의 필드 또는 속성).

바이트 복사가있을 수 있지만 JIT 컴파일러는 불필요한 복사본을 최대한 멀리 최적화하여 최대한 빨리 실행합니다. 일반적으로 걱정할 필요가 없습니다. 매우 미세한 최적화입니다.

이 질문에 대한 답변은 있습니까?

+0

동일한 함수를 반복해서 호출하면 새로운 Rectangle이 각 호출을 Draw에 푸시하고 Draw가 반환 할 때 튀어 나옵니까? – Bob

+0

예,하지만 스택 프레임을 누르고 터는 것은 포인터 (단일 기계 명령어)를 증가/감소시키는 것입니다. 그리고 JIT 컴파일러는 어쨌든 모든 것을 왕국에 최적화 할 것입니다. – thecoop

+0

@Bob : 이론적으로 JIT *가 동일한 호출을 볼 수 있고 여러 번 제출할 값을 캐시 할 수 있다고 생각하지만이 문제를 발견하는 데 필요한 휴리스틱을 고려하면 가능성이 매우 낮습니다. , 쉽게 배제 될 수 있습니다. –

1

값 유형은 스택에 있지만, 모든 프레임을 메모리에 할당하고 할당을 해제하는 데 여전히 성능 영향이 있습니다 (특히 Xbox 360). PC에서는 차이점을 눈치 채지 못할 것이지만 360 아마 것입니다.

+0

모든 값 형식이 스택에있는 것은 아닙니다. Customer 유형의 c가 int 유형의 값 유형 인 경우, 값은 여전히 ​​힙으로 이동합니다. – JonH

+0

정말요? 프레임의 시작 부분에 새로운 Rectangle을 만들어 재사용하는 것이 더 낫겠습니까? – Bob

+0

최선의 방법은 두 가지 방법으로 수백만 번 실행하고 어느 것이 더 빠르는지 확인하는 것입니다. 두 방법 모두에 대해 생성 된 IL을 비교할 수도 있습니다. – thecoop

1

값 유형은 로컬로 선언 된 경우 스택에 작성되거나 오브젝트 인스턴스의 일부인 경우 (오브젝트 인스턴스의 일부로) 작성됩니다. 어쨌든 구조체 인스턴스는 GC에 의해 수집되지 않고 컨테이너가 범위를 벗어나면 파괴됩니다.

MSDN struct (C#) 문서에 대한 자세한 내용이 있습니다.

1

이것은 thecoops 답변에 추가하기위한 것입니다. 참조 유형의 경우 new 연산자는 힙에 유형의 새 인스턴스를 할당하고 지정된 생성자를 호출합니다.

구조체의 경우 new 연산자는 지정된 생성자에 따라 필드를 초기화합니다. 그러나 new을 사용하지 않고 구조체를 인스턴스화 할 수 있습니다. 이 경우 구조체의 모든 필드는 초기화되지 않으므로 명시 적으로 초기화 될 때까지 사용할 수 없습니다.

자세한 내용은 the description on MSDN을 참조하십시오.

관련 문제