Đối tượng của mảng hay mảng của đối tượng?


13

Tôi đang thực hiện một trò chơi sim quản lý, một cái gì đó dọc theo dòng của Coaster Tycoon. Tôi muốn biết cách tốt nhất để cấu trúc các đối tượng thế giới của tôi là gì để tối đa hóa hiệu suất.

Hãy nói rằng tôi có 5.000 người trong trò chơi của mình, tôi có thể:

Tạo một đối tượng và lưu trữ chúng trong một mảng như vậy;

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

Hoặc tôi nên tạo một đối tượng gồm những người chứa nhiều mảng byte đại diện cho các thuộc tính của những người như vậy:

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

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

 // and so on....

Hay tôi hoàn toàn mất dấu?


Câu hỏi khá thú vị, đặc biệt là từ năm 2013, hơn một chục năm sau khi RCT xuất hiện, ý tưởng có 5000 NPC độc lập, có thể nhìn thấy trong một thế giới sẽ xuất hiện hoàn toàn không thể (mặc dù có những tiến bộ trong công nghệ)
Katana314

Câu trả lời:


15

Thuật ngữ phổ biến là "cấu trúc của mảng" (SOA) và "mảng cấu trúc" (AOS) xuất phát từ C và thường thấy nhất trong công việc của SIMD.

Thông thường, cách tiếp cận AOS nhanh hơn, nếu được sử dụng một cách thích hợp, nhưng SOA có xu hướng dễ làm việc hơn (và do đó tối ưu hóa cho chất lượng quan trọng hơn - thời gian phát triển).

SOA, đặc biệt là trong Java, có nghĩa là dữ liệu của bạn có thể được đóng gói chặt chẽ trong bộ nhớ. Bạn có thể lặp lại các thuộc tính và mong đợi bộ đệm CPU và như vậy vẫn hạnh phúc. Với AOS, đặc biệt là trong Java, mọi đối tượng đều được phân bổ "ở đâu đó" trong bộ nhớ. Lặp lại các đối tượng có khả năng làm hỏng bộ đệm CPU của bạn khá nhiều.

Cuối cùng, tôi sẽ chọn bất kỳ cách tiếp cận nào bạn thấy dễ sử dụng nhất. Thời gian phát triển của bạn có giá trị hơn nhiều so với việc trò chơi của bạn hỗ trợ PC 10 tuổi hay PC chỉ 9 tuổi (bạn rất khó có thể làm bất cứ điều gì htat cần phần cứng mới nhất).


1
Trong đoạn thứ ba của bạn, bạn có nghĩa là đề cập đến AOS hai lần? Các ý kiến ​​có vẻ mâu thuẫn ...
ali_goes_oosh

Xin lỗi, đã sửa nó lên.
Sean Middleditch

4

Không có lý do gì bạn không thể có cả hai, sử dụng mẫu Mặt tiền để dịch từ giao diện này sang giao diện cơ bản khác. Ví dụ: sử dụng thuật ngữ SOA / AOS của Sean:

Mặt tiền của SOA

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

Mặt tiền AOS

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

Bằng cách này, bạn có thể tự do lựa chọn giữa một hình thức mà bạn cảm thấy thoải mái khi sử dụng , như một giao diện dành cho nhà phát triển, so với bất kỳ điều gì tốt nhất khi triển khai vì bất kỳ lý do gì, bao gồm cả lý do hiệu quả / bộ đệm.

Một lợi thế khác cho mặt tiền là nó dẫn rất tự nhiên đến mẫu Flykg , nơi bạn sử dụng một giao diện để thể hiện nhiều người hơn so với thực tế trong bộ nhớ. Chẳng hạn, có lẽ bạn có những người bảo trợ robot không bao giờ khát; sau đó bạn có thể đặt trường hợp đặc biệt đó vào của bạn PersonFacadevà người dùng giao diện đó không bao giờ phải biết về robot:

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

... Hoặc sử dụng cách tiếp cận OO nhiều hơn, bạn sẽ có một Robotlớp riêng hoạt động chính xác như Personngoại trừ getThirst().


-1

Tạo các đối tượng và lưu trữ chúng trong một mảng! Tạo các mảng cho đóikhát có thể tiết kiệm một chút không gian và chạy nhanh hơn trong một số tình huống đơn giản, nhưng đó không phải là OOP. Java và OOP sẽ giúp ích rất nhiều cho bạn nếu bạn cho họ cơ hội. Đối với một trò chơi thực sự đơn giản, ví dụ thứ hai của bạn có thể hoạt động tốt, nhưng ngay cả khi đó bạn nên thực hành các kỹ năng OO của mình. Cách tiếp cận đầu tiên của bạn sẽ làm việc tốt cho bạn cho dù chương trình của bạn có lớn đến mức nào, phức tạp và nhiều lông.

Hãy nghĩ về tất cả các lần sẽ có ích để lấy lại một Personđối tượng từ một truy vấn. Ai đã gửi tin nhắn này? ví dụ. Rất nhiều phương pháp bạn viết sẽ muốn biết người họ đang làm việc với. Và bạn sẽ có rất nhiều phương pháp sẽ phù hợp với một Personlớp thích hợp . Nếu Personlà tĩnh hoặc đơn, bạn đặt phương thức tác động lên từng người ở đâu?

Nếu bạn từng thực hiện đa luồng - và với 5000 người dùng, bạn có thể bị đẩy vào đó - bạn sẽ thấy ví dụ Parent cho mỗi người dùng thực tế hơn rất nhiều.

. liệt kê mỗi danh sách đủ ngắn để là mảng hoặc danh sách được liên kết.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.