วัตถุของอาร์เรย์หรืออาร์เรย์ของวัตถุ?


13

ฉันกำลังสร้างเกมซิมการจัดการบางอย่างตามแนวของ 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....

หรือฉันปิดเครื่องหมายทั้งหมด?


คำถามที่น่าสนใจพริตตี้โดยเฉพาะอย่างยิ่งนับตั้งแต่ในปี 2013 มากกว่าสิบปีหลังจาก RCT ออกมาความคิดของการมี 5000 มองเห็น NPCs อิสระในโลกที่จะปรากฏเป็นไปไม่ได้อย่างทั่วถึง (แม้จะมีความก้าวหน้าในเทคโนโลยี)
Katana314

คำตอบ:


15

คำศัพท์ทั่วไปคือ "โครงสร้างของอาร์เรย์" (SOA) และ "อาร์เรย์ของโครงสร้าง" (AOS) ซึ่งมาจาก C และเห็นบ่อยที่สุดในแง่ของงาน SIMD

โดยทั่วไปแล้ววิธี AOS นั้นเร็วกว่าหากใช้อย่างเหมาะสม แต่ SOA มีแนวโน้มที่จะทำงานได้ง่ายขึ้น (และด้วยเหตุนี้จึงปรับให้เหมาะสมที่สุดสำหรับเวลาคุณภาพการพัฒนาที่สำคัญกว่า)

SOA โดยเฉพาะอย่างยิ่งใน Java หมายถึงข้อมูลของคุณจะยังคงอยู่ในหน่วยความจำแน่น คุณสามารถทำซ้ำคุณสมบัติและคาดว่าแคช CPU และยังคงมีความสุข ด้วย AOS โดยเฉพาะอย่างยิ่งใน Java วัตถุทุกชิ้นจะถูกจัดสรรในหน่วยความจำ การวนซ้ำวัตถุอาจทำให้แคช CPU ของคุณค่อนข้างหนักหน่วง

ในที่สุดฉันจะใช้วิธีใดก็ตามที่คุณพบว่าใช้ง่ายที่สุด เวลาในการพัฒนาของคุณนั้นมีค่ามากกว่าเกมของคุณที่รองรับพีซีอายุ 10 ปีหรือพีซีอายุเพียง 9 ปีเท่านั้น


1
ในย่อหน้าที่สามคุณหมายถึง AOS สองครั้งหรือเปล่า? ความคิดเห็นดูขัดแย้งกัน ...
ali_goes_oosh

ขออภัยทำการแก้ไข
Sean Middleditch

4

ไม่มีเหตุผลที่คุณไม่มีทั้งคู่ใช้รูปแบบ Facadeในการแปลจากอินเทอร์เฟซหนึ่งไปยังการแสดงพื้นฐานอื่น ๆ ตัวอย่างเช่นการใช้เงื่อนไข SOA / AOS ของ Sean:

ซุ้ม 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]; }
}

วิธีนี้คุณสามารถเลือกได้อย่างอิสระระหว่างแบบฟอร์มที่คุณพอใจกับการใช้เป็นส่วนต่อประสานนักพัฒนาเทียบกับสิ่งที่ดีที่สุดสำหรับการนำไปใช้ไม่ว่าด้วยเหตุผลใดก็ตามรวมถึงเหตุผลด้านประสิทธิภาพ / แคช

ข้อดีอีกอย่างของซุ้มคือนำไปสู่รูปแบบ Flyweightอย่างเป็นธรรมชาติซึ่งคุณใช้อินเทอร์เฟซเพื่อแสดงบุคคลมากกว่าที่อยู่ในหน่วยความจำ ตัวอย่างเช่นคุณอาจมีผู้อุปถัมภ์หุ่นยนต์ที่ไม่เคยกระหายน้ำ จากนั้นคุณสามารถใส่เคสพิเศษลงในของคุณ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()


-1

ทำวัตถุและเก็บไว้ในอาร์เรย์! การจัดเรียงอาเรย์เพื่อความหิวโหยและความกระหายอาจประหยัดพื้นที่และทำงานได้เร็วขึ้นในบางสถานการณ์ที่เรียบง่าย แต่ไม่ใช่ OOP Java และ OOP จะทำข้อตกลงที่ดีสำหรับคุณหากคุณให้โอกาสพวกเขา สำหรับเกมที่เรียบง่ายจริงๆตัวอย่างที่สองของคุณอาจทำงานได้ดี แต่ถึงอย่างนั้นคุณก็ควรฝึกฝนทักษะ OO ของคุณ วิธีการแรกของคุณจะทำงานได้ดีสำหรับคุณไม่ว่าโปรแกรมของคุณจะมีขนาดใหญ่ซับซ้อนและลำบากแค่ไหน

คิดถึงทุกครั้งที่จะมีประโยชน์ในการดึงPersonวัตถุกลับมาจากแบบสอบถาม ใครส่งข้อความนี้ เช่น จำนวนมากของวิธีการที่คุณเขียนจะต้องการที่จะรู้ว่าที่พวกเขากำลังจัดการกับ และคุณจะมีวิธีการมากมายที่จะเข้ากับPersonคลาสที่เหมาะสม ถ้าPersonเป็นแบบคงที่หรือเดี่ยวคุณจะวางวิธีที่ทำกับคนแต่ละคนที่ไหน?

หากคุณเคยทำ multithreading - และ 5000 ผู้ใช้ที่คุณอาจจะมีการผลักดันให้เป็นมัน - คุณจะพบตัวอย่างเช่นผู้ปกครองสำหรับผู้ใช้แต่ละคนจำนวนมากในทางปฏิบัติมากขึ้น

(และหลาย ๆ คน: ติดกับมันในตอนนี้ แต่ในบางจุดคุณจะต้องการอุปกรณ์จัดเก็บข้อมูลอื่น ๆ แผนที่บางประเภทเพื่อให้คุณสามารถค้นหาผู้คนตามชื่อและอาจมีหลายรายการที่มีคีย์แตกต่างกัน แสดงรายการสั้น ๆ พอที่จะเป็นอาร์เรย์หรือรายการที่ลิงก์)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.