Obyek array atau array objek?


13

Saya membuat game sim manajemen, sesuatu seperti Roller Coaster Tycoon. Saya ingin tahu apa cara terbaik untuk menyusun objek dunia saya sehingga memaksimalkan kinerja.

Katakanlah saya memiliki 5.000 orang di permainan saya, saya dapat:

Buat objek dan simpan dalam array seperti itu;

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;
    }

Atau haruskah saya membuat objek orang yang berisi banyak byte array yang mewakili atribut orang seperti:

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

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

 // and so on....

Atau apakah saya benar-benar melenceng?


Pertanyaan yang cukup menarik, terutama sejak tahun 2013, lebih dari selusin tahun setelah RCT keluar, gagasan memiliki 5.000 NPC independen yang terlihat di dunia akan tampak sangat mustahil (meskipun ada kemajuan dalam teknologi)
Katana314

Jawaban:


15

Terminologi yang umum adalah "struktur array" (SOA) dan "array struktur" (AOS) yang berasal dari C dan paling sering terlihat dalam hal kerja SIMD.

Biasanya, pendekatan AOS lebih cepat, jika digunakan dengan tepat, tetapi SOA cenderung lebih mudah untuk dikerjakan (dan karenanya mengoptimalkan untuk waktu pengembangan kualitas yang lebih penting).

SOA, terutama di Jawa, berarti bahwa data Anda dapat tetap dikemas dalam memori. Anda dapat mengulangi properti dan mengharapkan cache CPU dan semacamnya agar tetap bahagia. Dengan AOS, terutama di Jawa, setiap objek akhirnya dialokasikan "di suatu tempat" dalam memori. Iterasi lebih dari objek berpotensi merusak cache CPU Anda cukup banyak.

Pada akhirnya, saya akan mengambil pendekatan apa pun yang menurut Anda paling mudah digunakan. Waktu pengembangan Anda jauh lebih berharga daripada apakah game Anda mendukung PC berusia 10 tahun atau hanya PC berusia 9 tahun (Anda sangat tidak mungkin melakukan apa pun yang membutuhkan perangkat keras terbaru).


1
Dalam paragraf ketiga Anda, apakah Anda bermaksud merujuk ke AOS dua kali? Komentar-komentar itu tampaknya kontradiktif ...
ali_goes_oosh

Maaf, perbaiki.
Sean Middleditch

4

Tidak ada alasan Anda tidak dapat memiliki keduanya, menggunakan pola Facade untuk menerjemahkan dari satu antarmuka ke representasi lain yang mendasarinya. Misalnya, menggunakan istilah SOA / AOS Sean:

Fasad SOA

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

Fasad AOS

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

Dengan cara ini Anda dapat dengan bebas memilih antara formulir yang Anda nyaman gunakan , sebagai antarmuka pengembang, vs apa pun yang terbaik sebagai implementasi untuk alasan apa pun, termasuk alasan efisiensi / cache.

Keuntungan lain dari fasad adalah ia mengarah secara alami ke pola Flyweight , di mana Anda menggunakan antarmuka untuk mewakili lebih banyak orang daripada yang sebenarnya ada dalam memori. Sebagai contoh, mungkin Anda memiliki pelanggan robot yang tidak pernah haus; maka Anda dapat memasukkan case khusus ke dalam Anda PersonFacade, dan pengguna antarmuka itu tidak perlu tahu tentang robot:

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

... atau menggunakan pendekatan OO yang lebih, Anda akan memiliki Robotkelas terpisah yang bertindak persis seperti Personpengecualian getThirst().


-1

Buat objek dan simpan di dalam array! Membuat array untuk kelaparan dan kehausan dapat menghemat sedikit ruang dan berjalan lebih cepat dalam beberapa situasi sederhana, tetapi itu bukan OOP. Java dan OOP akan sangat membantu Anda jika Anda memberi mereka kesempatan. Untuk gim yang sangat sederhana, contoh kedua Anda mungkin bekerja dengan baik, tetapi meskipun begitu Anda harus melatih keterampilan OO Anda. Pendekatan pertama Anda akan bekerja dengan baik untuk Anda tidak peduli seberapa besar, kompleks, dan berbulu program Anda.

Pikirkan semua waktu itu akan berguna untuk mendapatkan Personobjek kembali dari permintaan. Siapa yang mengirim pesan ini? contohnya. Banyak metode yang Anda tulis ingin tahu dengan siapa mereka berhadapan. Dan Anda akan memiliki banyak metode yang cocok dengan Personkelas yang tepat . Jika Personstatis atau tunggal, di mana Anda meletakkan metode yang berlaku pada masing-masing orang?

Jika Anda pernah melakukan multithreading - dan dengan 5000 pengguna Anda mungkin didorong ke dalamnya - Anda akan menemukan contoh Induk untuk setiap pengguna jauh lebih praktis.

(Dan susunan orang itu: tetap gunakan untuk saat ini, tetapi pada titik tertentu Anda akan menginginkan perangkat penyimpanan lain. Peta semacam itu sehingga Anda dapat menemukan orang dengan nama. Dan mungkin beberapa daftar dengan kunci yang berbeda, dan mungkin sekelompok tandan daftar masing-masing cukup pendek untuk menjadi array atau daftar tertaut.)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.