2011-08-23 34 views
5

Tôi đang tạo trò chơi với Scala.Làm cho List.filter của tôi nhanh hơn trên Scala?

Trò chơi của tôi có một số hồ bơi để giữ kẻ thù. Họ là những danh sách bất biến bởi vì chúng được khởi tạo với kích thước đủ nên (vì việc tạo ra các thể hiện kẻ thù mới trong game rất tốn kém).

Trò chơi của tôi biết nếu kẻ thù còn sống bằng cách yêu cầu enemy.isVisible. Vì vậy, CollisionHandler tôi hoạt động như:

  1. Kết hợp tất cả các kẻ thù sống vào một danh sách
  2. Nhận đạn sống
  3. phân vùng không gian này và làm phát hiện va chạm cho đạn và kẻ thù trong phân vùng không gian tương tự

Điều làm tôi ngạc nhiên là theo hồ sơ, bước 1 mất phần lớn thời gian. Và những gì bước điều đó không được về cơ bản nói:

def allActiveEnemies = List(enemyType1.getAllActive, enemyType2.getAllActive, ...).flatten 

các flatten có vẻ không đắt nhưng thay vào đó nó nhận được cuộc gọi getAllActive. Họ đang thực hiện trong đặc điểm Pooled của tôi như thế này:

trait Pooled[T <: Entity] { 
    var pool = List[T]() 
    val INITIAL_POOL_SIZE:Int 

    def initPool() { 
     for(i<-1 to INITIAL_POOL_SIZE) 
     { 
      addToPool(disable(createNew)) 
     } 
    } 

    def getAllActive:List[T] = pool.filter(e => e.isVisible) 
} 

(tôi bỏ qua hầu hết các đặc điểm bởi vì tôi không nghĩ rằng nó có liên quan ở đây.)

pool.filter là những gì đốt cháy như 45% tổng thời gian dành cho CollisionHandler, điều này có vẻ rất lạ.

Mọi đề xuất để làm mọi thứ nhanh hơn ở đây?

Có thể sử dụng ArrayLists thay vì Danh sách? Có thể sử dụng một số bộ sưu tập phân loại và có thể thay đổi? Hay tôi chỉ đơn giản là làm điều gì đó khủng khiếp sai?

Cảm ơn!

+0

có thể truy cập trường hoặc tính toán? – huynhjl

+0

isVisible là một getter cho một lĩnh vực (như tôi đang sử dụng một công cụ trò chơi dựa trên Java làm cơ sở cho trò chơi của tôi). – vertti

+0

Tôi có lẽ nên thêm rằng tôi đang sử dụng Scala 2.8.1 và trò chơi được chạy trên Android 2.x – vertti

Trả lời

4

Các hồ bơi này rộng bao nhiêu? Bạn biết rằng mỗi khi bạn tạo danh sách, bạn phải tạo một đối tượng mới để giữ mỗi mục nhập. Bạn có thể cắt giảm điều này một chút bằng cách sử dụng chế độ xem trên bộ lọc (ví dụ: pool.view.filter(e => e.isVisible); sau đó trả lại Seq[T]). Nói chung, tôi nghĩ rằng chiến lược của bạn nên được không làm thêm lọc làm việc mỗi lần. Theo dõi kẻ thù hoạt động của bạn trong một Set hoặc một cái gì đó; sau đó bạn có chúng khi bạn cần chúng.

+0

Các hồ bơi hiện có khoảng 40 và có 5 trong số đó. Nhưng cả hai con số sẽ tăng lên khi chúng tôi tiến bộ trong trò chơi của chúng tôi, vì vậy một dự đoán sẽ là kích thước hồ bơi khoảng 100 và 10-15 hồ bơi. – vertti

+0

@vertti - Điều đó không nên mất thời gian đáng chú ý nào cả - có thể là một phần nghìn giây hoặc hai ở mức rất tệ nhất. –

+0

Trình thông báo trên Android cho biết khoảng 27msec cho CollisionHandler, một nửa trong số đó cho các trình thu thập dữ liệu getActive. :(Điều đó đã đủ để tác động đến tốc độ khung hình đáng kể – vertti

Các vấn đề liên quan