2011-09-08 29 views
10

Tôi đang làm việc trên trò chơi Windows Phone 7 XNA. Đó là một cổng của trò chơi được viết bằng C++, và như vậy, tôi đang cố gắng viết lại ít đoạn mã gameplay nhất có thể.Chuỗi có thể thay đổi trong WP7 C#/XNA?

Rác là vấn đề lớn trên WP7, vì bộ thu không phát triển và chậm, nên bộ sưu tập (được kích hoạt mỗi 1MB) mất khoảng 10ms cho mỗi MB phân bổ. Tôi hoàn toàn có ý định sử dụng tối đa 90MB có sẵn, vì vậy chúng tôi đang xem xét một ~ 900ms gian hàng mỗi MB phân bổ.

Tôi đã có thể làm lại những thứ để chúng tôi không tạo ra rác trên mỗi khung hình, ngoại trừ một vài trường hợp dây.

Dường như StringBuilder.ToString() tạo ra rác và phương pháp được mô tả here không hoạt động trên WP7.

Hai điều tôi cần phải làm là: phút

  • Format/giây/hundreths như mm: ss.hh để hiển thị ra màn hình. Rõ ràng tôi có thể làm điều đó với một StringBuilder (sử dụng các phương thức mở rộng không tạo ra rác từ boxing ints) và hiển thị StringBuilder trực tiếp với SpriteBatch.
  • Tách một chuỗi có dạng "foo.bar.baz.qux" thành một mảng trên '.', Tức là {"foo", "bar", "baz", "qux"} và sao chép một phần tử tại thời gian vào một chuỗi các chuỗi. Điều này là để thiết lập trạng thái phân cấp của các diễn viên trò chơi. Nó cũng được chuyển trực tiếp khá nhiều từ game gốc, và khá phụ thuộc vào nó hoạt động theo cách này. Tôi thực sự muốn tránh viết lại nó.

Ngắn chuyển đổi rất nhiều mã để sử dụng char [] thay vì chuỗi, có cách nào để có chuỗi có thể thay đổi không rác thực sự trong C# không?

+2

Chỉ một bên xoài chú ý có Generational GC http://blogs.msdn.com/b/abhinaba/archive/2011/04/13/generational-gc-in-windows-phone-mango.aspx – Terrance

+0

Đây cũng là một cách để làm điều gì đó "gần gũi hơn" với các chuỗi có thể thay đổi được http://stackoverflow.com/questions/6913435/how-to-get-a-list-of-mutable-strings – Terrance

Trả lời

10

Tại sao bạn cần phải chuyển đổi một số StringBuilder thành số String ngay từ đầu? Như bạn đã lưu ý, bạn có thể chuyển trực tiếp StringBuilder trực tiếp vào các phương thức vẽ của XNA. Bạn cũng có thể sử dụng StringBuilder để lấy chuỗi con:

substringBuilder.Length = 0; 
for (int i = start; i <= end; i++) 
    substringBuilder.Append(originalBuilder[i]); 

Những điều duy nhất bạn muốn tránh với StringBuilderToString()AppendFormat(). Không có phương pháp định dạng nào khác (theo kiến ​​thức của tôi) tạo ra rác. Cập nhật: Tôi đã sai. Viết các phương thức mở rộng của riêng bạn. Một tóm tắt có sẵn tại đây: Avoiding garbage when working with StringBuilder

Viết tương đối dễ dàng một phương thức sẽ chia chuỗi thành các chuỗi dựa trên một dấu phân cách nhất định. Chỉ cần nhớ rằng String.Split() là điều xấu cho hai lý do - đầu tiên, vì nó phân bổ chuỗi mới; và thứ hai, bởi vì nó phân bổ mảng mới. Sự bất biến của dây chỉ là một nửa vấn đề của bạn.

Hãy xem xét các phương pháp mở rộng sau đây cho StringBuilder. Tôi đã không kiểm tra kỹ mã này, nhưng nó sẽ cho bạn một ý tưởng chung. Lưu ý rằng nó hy vọng bạn vượt qua trong một mảng được phân bổ trước, sau đó nó sẽ cư trú.

public static void Substring(this StringBuilder source, Int32 start, Int32 count, StringBuilder output) 
{ 
    output.Length = 0; 
    for (int i = start; i < start + count; i++) 
    { 
     output.Append(source[i]); 
    } 
} 

public static int Split(this StringBuilder source, Char delimiter, StringBuilder[] output) 
{ 
    var substringCount = 0; 
    var substringStart = 0; 
    for (int i = 0; i < source.Length; i++) 
    { 
     if (source[i] == delimiter) 
     { 
      source.Substring(substringStart, i - substringStart, output[substringCount]); 
      substringCount++; 
      substringStart = i + 1; 
     } 
    } 
    if (substringStart < source.Length - 1) 
    { 
     source.Substring(substringStart, source.Length - substringStart, output[substringCount]); 
     substringCount++; 
    } 
    return substringCount; 
} 
+1

Định dạng các đối tượng không phải chuỗi (ví dụ: số) sẽ tạo ra rác (nó gọi phương thức 'ToString' của họ). Nhưng nó là khá tầm thường để viết một phương pháp mở rộng miễn phí rác để thêm số nguyên (hoặc hầu hết các loại khác, thực sự). Bạn có thể tìm thấy các ví dụ khá dễ dàng trực tuyến. –

+0

Giao diện nhanh chóng thông qua nguồn được giải mã xác nhận rằng bạn đã chính xác. Tôi không chắc tại sao tôi lại nghĩ khác. Nhưng có, bạn có thể làm việc xung quanh điều này. –

0

Tôi đang cố gắng viết lại ít mã gameplay nhất có thể.

Cẩn thận với điều đó có thể mất nhiều thời gian hơn để viết lại. Cole Campbell là đúng, không có điểm gọi ToString() trong khi bạn muốn vẽ nó. XNA có phương thức vẽ lấy StringBuldier và nó hoạt động tốt trong trò chơi của tôi.

Một giải pháp khác cho vấn đề của bạn: tạo HashSet toàn bộ chuỗi của bạn và thiết lập nó khi bạn tải trò chơi hoặc cấp độ để tránh áp lực thu thập.

Cố gắng làm càng nhiều càng tốt khi bạn tải trò chơi.

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