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
정확하게 작동 하는 별도의 클래스가 있습니다.Person
getThirst()
답변
객체를 만들어 배열에 저장하십시오! 굶주림 과 갈증을 위해 배열을 만들면 약간의 공간을 절약하고 일부 간단한 상황에서 더 빠르게 실행될 수 있지만 OOP는 아닙니다. Java와 OOP는 기회를 주면 많은 도움이 될 것입니다. 정말 간단한 게임의 경우, 두 번째 예는 잘 작동 수도 있지만, 그렇다하더라도 당신은 해야 당신의 OO 기술을 연습 할 수. 첫 번째 접근 방식은 프로그램이 얼마나 크고 복잡하며 털이 많은지에 관계없이 잘 작동합니다.
Person
쿼리에서 개체를 다시 가져 오는 것이 편리한 모든 시간을 생각하십시오 . 누가이 메시지를 보냈습니까? 예를 들어. 당신이 쓰는 많은 방법 들이 그들이 누구 를 다루고 있는지 알고 싶어 할 것 입니다 . 그리고 당신은 적절한 Person
클래스 에 잘 맞는 많은 메소드를 갖게 될 것 입니다. 만약Person
당신이 방법을 배치해야합니까 정적 또는 싱글 톤이며, 개별 사용자에 관한 법률이?
멀티 스레딩을 수행하는 경우 (5000 명의 사용자가있는 경우) 각 사용자의 Parent 인스턴스가 훨씬 실용적입니다.
(그리고 그 사람들의 배열 : 지금은 그것을 고수하고 있지만, 언젠가는 다른 저장 장치를 원할 것입니다. 어떤 종류의지도는 이름으로 사람들을 찾을 수 있습니다. 그리고 아마도 다른 키를 가진 여러 목록과 아마도 많은 무리가 있습니다. 배열 또는 연결된 목록이 될 수있을만큼 짧은 각 목록.)