배열의 개체 또는 개체의 배열?

Roller Coaster Tycoon 라인을 따라 관리 시뮬레이션 게임을 만들고 있습니다. 월드 오브젝트를 구성하는 가장 좋은 방법이 성능을 극대화하는 방법을 알고 싶습니다.

내 게임에 내가 할 수있는 사람이 5,000 명이라고 가정 해 봅시다.

객체를 만들어서 배열에 저장하십시오.

class person() {
    this.x = 0;
    this.y = 0;
    this.thirst = 15;
    this.hunger = 15;
    // etc.. add methods:
    public findPath(int destX, int destY) {
    // and so on
    }

    people = new person[5000];

for (int = 0; i < 5000; i++) {
    people[i] = new person;
    }

또는 사람들의 속성을 나타내는 많은 바이트 배열을 포함하는 사람들의 객체를 만들어야합니다.

class people() {
    this.hunger = new byte[5000]
    this.thirst = new byte[5000]

    getThirst(int i) {
        return this.thirst[i]
        }

 // and so on....

아니면 마크에서 완전히 벗어 났습니까?



답변

일반적인 용어는 “배열 구조”(SOA)와 “배열 구조”(AOS)로 C에서 나오며 SIMD 작업 측면에서 가장 많이 나타납니다.

일반적으로 AOS 접근 방식은 적절하게 사용하면 더 빠르지 만 SOA는 작업하기가 더 쉬워 지므로보다 중요한 품질-개발 시간에 최적화됩니다.

SOA, 특히 Java의 경우 데이터가 메모리에 단단히 채워져있을 수 있습니다. 속성을 반복하고 CPU 캐시 등이 만족할 것으로 기대할 수 있습니다. AOS, 특히 Java에서는 모든 객체가 메모리의 “어딘가”에 할당됩니다. 객체를 반복하면 CPU 캐시가 크게 손상 될 수 있습니다.

결국, 나는 당신이 사용하기 가장 쉬운 방법을 취합니다. 개발 시간은 게임이 10 년 된 PC를 지원하는지 또는 9 년 된 PC 만 지원하는지보다 훨씬 중요합니다 (최신 하드웨어가 필요한 작업은 거의 없을 것입니다).


답변

하나의 인터페이스에서 다른 기본 표현으로 변환하기 위해 Facade 패턴 을 사용하여 둘 다 가질 수있는 이유는 없습니다 . 예를 들어 Sean의 SOA / AOS 용어를 사용하면 다음과 같습니다.

SOA 외관

class PeopleFacade {
    Person persons[5000];
    getThirst(int i) { return persons[i].thirst; }
}

AOS 정면

class People { int thirsts[5000]; } people;
class PersonFacade {
    int i;
    getThirst() { return people.thirsts[i]; }
}

이 방법을 사용 하면 개발자 인터페이스로 사용하기 편한 형식과 효율성 / 캐시 이유 등 어떤 이유로 든 구현에 가장 적합한 형식 중에서 자유롭게 선택할 수 있습니다 .

파사드의 또 다른 장점 은 인터페이스가 실제로 메모리에있는 것보다 훨씬 많은 사람을 나타내는 인터페이스를 사용하는 플라이 웨이트 패턴 으로 매우 자연스럽게 연결된다는 것 입니다. 예를 들어, 아마도 목 마르지 않는 로봇 후원자가있을 것입니다. 그런 다음 특수 사례를에 넣을 PersonFacade수 있으며 해당 인터페이스의 사용자는 로봇에 대해 알 필요가 없습니다.

class People { int nonRobotThirsts[1000]; } people;
class PersonFacade {
    int i;
    bool isRobot;
    getThirst() {
        if (isRobot)
            return 0;
        else
            return people.nonRobotThirsts[i];
    }
}

… 또는 더 많은 OO 접근 방식을 사용하면를 제외하고 Robot정확하게 작동 하는 별도의 클래스가 있습니다.PersongetThirst()


답변

객체를 만들어 배열에 저장하십시오! 굶주림갈증을 위해 배열을 만들면 약간의 공간을 절약하고 일부 간단한 상황에서 더 빠르게 실행될 수 있지만 OOP는 아닙니다. Java와 OOP는 기회를 주면 많은 도움이 될 것입니다. 정말 간단한 게임의 경우, 두 번째 예는 잘 작동 수도 있지만, 그렇다하더라도 당신은 해야 당신의 OO 기술을 연습 할 수. 첫 번째 접근 방식은 프로그램이 얼마나 크고 복잡하며 털이 많은지에 관계없이 잘 작동합니다.

Person쿼리에서 개체를 다시 가져 오는 것이 편리한 모든 시간을 생각하십시오 . 누가이 메시지를 보냈습니까? 예를 들어. 당신이 쓰는 많은 방법 들이 그들이 누구 를 다루고 있는지 알고 싶어 할 것 입니다 . 그리고 당신은 적절한 Person클래스 에 잘 맞는 많은 메소드를 갖게 될 것 입니다. 만약Person 당신이 방법을 배치해야합니까 정적 또는 싱글 톤이며, 개별 사용자에 관한 법률이?

멀티 스레딩을 수행하는 경우 (5000 명의 사용자가있는 경우) 각 사용자의 Parent 인스턴스가 훨씬 실용적입니다.

(그리고 그 사람들의 배열 : 지금은 그것을 고수하고 있지만, 언젠가는 다른 저장 장치를 원할 것입니다. 어떤 종류의지도는 이름으로 사람들을 찾을 수 있습니다. 그리고 아마도 다른 키를 가진 여러 목록과 아마도 많은 무리가 있습니다. 배열 또는 연결된 목록이 될 수있을만큼 짧은 각 목록.)