Dizilerin nesnesi mi, nesne dizisi mi?


13

Roller Coaster Tycoon çizgisinde bir yönetim sim oyunu yapıyorum. Performansımı en üst düzeye çıkarmak için dünya nesnelerimi yapılandırmanın en iyi yolunun ne olduğunu bilmek istiyorum.

Diyelim ki oyunumda 5.000 kişi var:

Bir nesne oluşturun ve bunları böyle bir dizide saklayın;

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

Yoksa böyle insanların özelliklerini temsil eden birçok bayt dizisi içeren bir nesne yapmalıyım:

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

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

 // and so on....

Yoksa tamamen izim yok mu?


Oldukça ilginç bir soru, özellikle RCT'nin ortaya çıkmasından bir düzine yıl sonra 2013'te beri, bir dünyada 5000 görünür, bağımsız
NPC'ye

Yanıtlar:


15

Genel terminoloji, C'den gelen ve çoğunlukla SIMD çalışması açısından görülen "dizilerin yapısı" (SOA) ve "yapı dizisi" dir (AOS).

Tipik olarak, uygun şekilde kullanılırsa AOS yaklaşımı daha hızlıdır, ancak SOA ile çalışmak daha kolay olma eğilimindedir (ve dolayısıyla daha önemli kalite geliştirme süresi için optimize eder).

SOA, özellikle Java'da, verilerinizin bellekte sıkıca kalabileceği anlamına gelir. Özellikler üzerinde yineleme yapabilir ve CPU önbelleğinin ve benzerlerinin mutlu kalmasını bekleyebilirsiniz. AOS ile, özellikle Java'da, her nesne bellekte "bir yere" tahsis edilir. Nesneler üzerinde yineleme yapmak CPU önbelleğinizi oldukça yoğun bir şekilde tehlikeye atabilir.

Sonunda, kullanmak için en kolay bulduğunuz yaklaşımı benimserim. Geliştirme süreniz, oyununuzun 10 yıllık PC'leri mi yoksa sadece 9 yaşındaki PC'leri mi desteklediğinden çok daha değerlidir (en son donanıma ihtiyaç duyan herhangi bir şey yapmanın pek olası olmadığını).


1
Üçüncü paragrafınızda AOS'a iki kez atıfta bulunmak mı istiyorsunuz? Yorumlar çelişkili görünüyor ...
ali_goes_oosh

Üzgünüm, düzelttim.
Sean Middleditch

4

Bir arabirimden diğer temel temsile çevirmek için Cephe desenini kullanarak her ikisine birden sahip olmanız için hiçbir neden yoktur . Örneğin, Sean'ın SOA / AOS terimlerini kullanarak:

SOA cephe

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

AOS cephe

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

Bu şekilde , geliştirici arayüzü olarak kullanmakta rahat olduğunuz bir form arasında , verimlilik / önbellek nedenleri de dahil olmak üzere herhangi bir nedenle uygulama olarak en iyi olanı seçebilirsiniz .

Cephenin bir diğer avantajı, aslında doğal olarak bellekte olandan çok daha fazla kişiyi temsil etmek için bir arayüz kullandığınız Flyweight desenine yol açmasıdır . Örneğin, belki de asla susamayan robotik kullanıcılarınız var; o özel durumu sizin durumunuza koyabilirsiniz PersonFacadeve bu arayüzün kullanıcıları hiçbir zaman robotları bilmek zorunda kalmaz:

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

... ya da daha fazla bir OO yaklaşımı kullanarak, Robottam olarak Persondışındakiler gibi davranan ayrı bir sınıfınız olur getThirst().


-1

Nesneler oluşturun ve bunları bir dizide saklayın! Açlık ve susuzluk için diziler yapmak biraz yer tasarrufu sağlayabilir ve bazı basit durumlarda daha hızlı çalışabilir, ancak OOP değil. Eğer onlara bir şans verirseniz, Java ve OOP sizin için çok şey yapar. Gerçekten basit bir oyun için, ikinci örnek ince işe yarayabilir, ama o zaman bile size gereken sizin OO becerilerini pratik olması. Programınız ne kadar büyük, karmaşık ve tüylü olursa olsun ilk yaklaşımınız sizin için iyi sonuç verecektir.

Bir Personnesneyi bir sorgudan geri almanın her zaman kullanışlı olacağını düşünün . Bu mesajı kim gönderdi? Örneğin. Yazdığınız birçok yöntem kiminle uğraştıklarını bilmek isteyecektir . Ve uygun bir Personsınıfa güzel uyacak birçok yönteminiz olacak . Eğer Personsiz yöntemleri koyacağım statik veya bir tekil, bireysel insanlar üzerinde hareket olduğunu?

Birden çok iş parçacığı uygularsanız - ve 5000 kullanıcıyla buna itilebilirseniz - her kullanıcı için Ana örneği çok daha pratik bulacaksınız .

(Ve bu insan dizisi: şimdilik buna uyun, ancak bir noktada diğer depolama cihazlarını isteyeceksiniz. İnsanları adlarına göre bulabileceğiniz bir çeşit Harita. Ve belki de farklı anahtarlara sahip birkaç liste ve muhtemelen her biri diziler veya bağlantılı listeler olacak kadar kısa listeler.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.