간단한 효율성 질문 C ++ (메모리 할당) .. 그리고 일부 충돌 감지에 도움이됩니까?

StackOverflow https://stackoverflow.com/questions/333285

문제

C ++ (다 방향 2D 우주 사수)로 작은 아케이드와 같은 게임을 작성하고 충돌 감지 부분을 마무리하고 있습니다.

다음은 내가 그것을 구성하는 방법입니다 (방금 만들었으므로 시끄러운 시스템이 될 수 있습니다) :

모든 선박은 원형 구성 요소로 구성되어 있습니다. 각 선박의 구성 요소의 양은 일종의 임의입니다 (더 많은 구성 요소, 더 많은 CPU 사이클). 나는 선박의 생성시 계산할 때 최대의 거리를 가지고 있으며, 기본적으로 선박의 중심에서 가장 먼 곳에서 가장 긴 구성 요소의 가장자리까지 끌 수있는 가장 긴 선입니다. 나는 화면에 물건을 추적 하고이 MaxComponentDistance를 사용하여 충돌하기에 충분히 가까운 지 확인합니다.

그들이 근접한 경우, 나는 다른 선박의 구성 요소가 교차하는지 확인하기 시작합니다. 여기 내 효율성 질문이 발생하는 곳이 있습니다.

선박 중심에 대한 구성 요소의 (x, y) 위치가 있지만 선박이 현재 회전하는 방식을 설명하지 않습니다. 나는 배가 움직일 때마다 구성 요소를 다시 계산하고 싶지 않기 때문에 상대적으로 유지합니다. 따라서 회전 계산에 대한 공식이 약간이며 선박 센터에 대한 회전이주고되는 위치에 해당하는 2D 벡터를 반환합니다.

충돌 감지는 GameEngine에 있으며 2D 벡터를 사용합니다. 내 질문은 반환 유형에 관한 것입니다. 함수가 호출되거나 해당 구성 요소 개체를 추가 개인 2D- 벡터 변수를 제공하고 함수가 호출 될 때 개인 변수를 편집하고 해당 개체에 대한 포인터를 반환해야합니까?

메모리 할당의 효율성과 영구적이고 편집 가능한 개인 변수가있는 것에 대해 잘 모르겠습니다. 나는 메모리가 개인 변수에 대해서도 할당되어야한다는 것을 알고 있지만, 새로운 구성 요소가 생성 된 경우에만 충돌을 확인할 때마다 할당되지는 않습니다. 선박이 파괴 될 때 삭제되므로 구성 요소는 내 환경에서 일정하지 않습니다.

그것이 나의 주요 딜레마입니다. 또한 실제 충돌 감지 시스템의 설계에 대한 포인터도 감사합니다. 처음으로 해킹을 했어요 (어쩌면 조금 읽었어야했을 것입니다)

미리 감사드립니다.

도움이 되었습니까?

해결책

Getter 기능에 대한 각 호출마다 구성 요소 벡터에 대한 메모리 할당을 피하려고 노력해야합니다. 대신 가능한 한 거의 할당을 거의 할당하십시오. 예를 들어, 선박의 구성 요소 구성이 변경되거나 훨씬 더 거의 (과도하게 할당) 할 수 있습니다.

물론 많은 구성 요소를 사전 할당하고 풀에 넣는 메모리 풀을 조사 할 수도 있으므로 일정한 시간에 새로운 구성 요소를 할당 할 수 있습니다.

이런 종류의 충돌 감지를 할 때 일반적인 (그리고 너무 명백한 경우 사과)로서 정사각형 뿌리를 계산하기보다는 거리를 제곱합니다. :)

다른 팁

2D 벡터가 단지 :

 class Vector2D { double x, y; };

그런 다음 반드시 반환하십시오! 예 :

  Vector2D function( ... );

또는 참조별로 통과 :

  void function( Vector2D * theReturnedVector2D, ... );

모든 비용을 피하십시오.

 vector<double> function(...);

벡터 클래스에 내재 된 상수 힙 할당/거래는 실수입니다!


자신의 vector2d 클래스를 복사하는 것은 매우 저렴하며 계산적으로 말하면됩니다. Vector <>와 달리 자신의 vector2d 클래스는 원하는 방법을 통합 할 수 있습니다.

과거 에이 기능을 사용하여 distancetootherpointsquared (), scanffromcommandlinearguments (), printfnicelyformatted () 및 연산자 [] (int)와 같은 메소드를 통합했습니다.


아니면 해당 구성 요소 개체를 추가 개인 2D 벡터 변수를 제공하고 함수가 호출 될 때 개인 변수를 편집하고 해당 객체에 대한 포인터를 반환해야합니까?

이전 데이터를 무효화하는 여러 기능 호출을 조심하십시오. 그것은 재난을위한 레시피입니다!

  1. 벡터를 반환하고 벤치마킹하여 시작할 수 있습니다. 누가 충분히 빠를 수 있는지 알 수 있습니다. 프로파일 러를 사용하면 시간이 걸리는 부분을 볼 수 있습니다.
  2. 당신은 a를 사용할 수 있습니다 메모리 풀 벡터를 재사용하고 복사를 줄입니다
  3. 당신은 시도 할 수 있습니다 플라이급 패턴 좌표가 엔진 전체에서 반복되는 경우 복사 및 할당을 줄입니다.
  4. 구성 요소에 데이터를 유지하는 것은 할당을 줄이는 좋은 방법이지만 벡터를 사용하는 사람이 구성 요소의 수명주기에 의존하는 것처럼 일부 gotchas를 설계에 소개합니다. 메모리 풀이 더 나을 것입니다.

2D 벡터를 사용하지 마십시오. 오히려 a vectorpoint에스. 충돌 감지와 마찬가지로. 여기서 2D 벡터를 사용하는 것은 잘못된 데이터 구조입니다.

함수의 내용에 따라 컴파일러는 NRVO를 수행 할 수 있습니다 (즉, 리턴 값 최적화 명명) 이는 최적의 경우 벡터를 반환하는 것이 아니요 오버 헤드, 즉 복사 한 적이 없습니다. 그러나 기능의 반환 값을 사용하여 새 인스턴스를 초기화하고 컴파일러가 함수 내부의 실행 경로를 추적하고 각 반환 경로에 대해 동일한 개체가 반환되는지 확인할 때만 발생합니다. 다음 두 가지를 고려하십시오.

vector<int> f(int baz) {
    vector<int> ret;
    if (baz == 42)
        ret.push_back(42);
    return ret;
}

vector<int> g(int baz) {
    if (baz == 42)
        return vector<int>(1, 42);
    else
        return vector<int>();
}

컴파일러는 통화를 위해 NRVO를 수행 할 수 있습니다 f, 그러나 그렇지 않습니다 g.

힙과 스택에 메모리 할당 사이에는 큰 차이가 있습니다. 새/삭제 또는 malloc/free를 사용하여 힙에 할당하는 것은 매우 느립니다. 스택에 할당하는 것은 정말 빠릅니다. 스택을 사용하면 일반적으로 느린 부분은 물체를 복사하는 것입니다. 따라서 벡터 등을 조심하지만 간단한 구조를 반환해도 괜찮을 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top