2010-11-06 25 views
10

Tôi có một câu hỏi đơn giản đến nỗi tôi không thể tin rằng mình không thể tự trả lời được. Nhưng, có bạn đi.Sử dụng một mảng tĩnh lớn trong C# (Silverlight trên Windows Phone 7)

Tôi có danh sách tĩnh lớn (của các thành phố, vĩ độ và kinh độ) mà tôi muốn sử dụng trong ứng dụng Silverlight Windows Phone 7 của mình. Có khoảng 10.000 người trong số họ. Tôi muốn nhúng dữ liệu này tĩnh trong ứng dụng của tôi và truy cập nó trong một mảng (tôi cần phải chuyển qua toàn bộ danh sách trong mã khá thường xuyên).

Điều gì sẽ là phương tiện lưu trữ hiệu quả nhất của tôi? Tôi là một chút của một loại trường cũ, vì vậy tôi xem thuộc cách nhanh nhất để làm điều đó sẽ là:

public struct City 
{ 
    public string name; 
    public double lat; 
    public double lon; 
}; 

và sau đó ...

private City[] cc = new City[10000]; 

public CityDists() 
{ 
    cc[2].name = "Lae, Papua New Guinea"; cc[2].lat = 123; cc[2].lon = 123; 
    cc[3].name = "Rabaul, Papua New Guinea"; cc[3].lat = 123; cc[3].lon = 123; 
    cc[4].name = "Angmagssalik, Greenland"; cc[4].lat = 123; cc[4].lon = 123; 
    cc[5].name = "Angissoq, Greenland"; cc[5].lat = 123; cc[5].lon = 123; 
... 

Tuy nhiên, bums này ra với một " ra khỏi bộ nhớ "lỗi trước khi mã thực sự được chạy (tôi giả định mã chính nó đã kết thúc được quá nhiều để tải vào bộ nhớ).

Mọi thứ tôi đọc trực tuyến đều yêu cầu tôi sử dụng tài nguyên XML hoặc tệp và sau đó để deserialise vào trường hợp của một lớp. Nhưng điều đó có thể thực sự nhanh như sử dụng cấu trúc không? Liệu XML có mất thời gian để phân tích cú pháp không?

Tôi nghĩ rằng tôi có khả năng viết mã ở đây - Tôi chỉ không chắc cách tiếp cận tốt nhất là bắt đầu bằng. Tôi quan tâm đến tốc độ tải và (quan trọng hơn) thời gian chạy truy cập nhiều hơn bất cứ điều gì.

Bất kỳ sự trợ giúp nào được đánh giá cao - câu hỏi đầu tiên ở đây vì vậy tôi hy vọng tôi đã không làm bất cứ điều gì đầu óc.

Chris

+0

Xin chào Chris, Tổng lượng dữ liệu trong tổng số là bao nhiêu? Bao nhiêu bộ nhớ trên hệ thống của bạn và hoàn toàn miễn phí? Tôi giả sử bạn đang thử nghiệm trên emu. Ngoài ra tò mò nếu bạn không nhớ tôi hỏi những gì nguồn dữ liệu là .. Tôi đã xem xét các tùy chọn cho dữ liệu thành phố quá. –

+0

Để tham chiếu 100k dữ liệu XML đơn giản có thể được tải từ XAP sử dụng XDocument, hiển thị trong hộp danh sách và được lưu vào bộ nhớ riêng biệt trong 0.5 giây trên thiết bị 650Mhz. –

+12

Xin chào Mick - Tôi đang sử dụng dữ liệu đến từ http://www.partow.net/miscellaneous/airportdatabase/index.html. Có một số thứ rác rưởi ở đó mà tôi đã loại bỏ và tôi đã chuyển đổi vĩ độ và kinh độ thành chỉ số - nếu có cách nào đó bạn có thể liên lạc với tôi, tôi rất vui được chia sẻ kết quả cuối cùng (trong bảng tính Excel ngay bây giờ). Tôi sẽ nhìn vào XDocument - nghe có vẻ dễ dàng đủ nhanh cho những gì tôi theo sau! –

Trả lời

1

Nếu tải một doc xml từ XAP làm việc cho bạn ..

Dưới đây là một dự án tôi đã đăng thể hiện tải của một doc xml từ XAP thông qua XDocument/LINQ và databinding vào một listbox để tham khảo.

binding a Linq datasource to a listbox

+0

Điều này làm việc tuyệt vời, cảm ơn rất nhiều. Tôi đã hoàn thành việc dọn dẹp dữ liệu và tôi có 3000 thành phố với vĩ độ và kinh độ - vui lòng liên lạc nếu bạn muốn! –

+0

yw:) ... Tôi đã lưu liên kết, ty :) –

3

10.000 cấu trúc không nên chạy ra khỏi bộ nhớ, nhưng chỉ để chắc chắn, lần đầu tiên tôi sẽ cố gắng biến struct của bạn vào một lớp học như vậy mà nó sử dụng đống thay cho chồng. Có một khả năng mạnh mẽ mà làm điều đó sẽ sửa chữa của bạn ra khỏi bộ nhớ lỗi.

Một tệp XML được lưu trữ trong bộ nhớ riêng biệt có thể là một cách hay để truy cập nếu dữ liệu của bạn sẽ được cập nhật ngay cả trong từng thời điểm. Bạn có thể kéo các thành phố từ một dịch vụ web và sắp xếp các lớp đó vào Kho Ứng dụng trong bộ nhớ riêng biệt bất cứ khi nào chúng được cập nhật.

Ngoài ra, tôi nhận thấy trong các mẫu mã mà mảng cc không được khai báo tĩnh. Nếu bạn có một vài trường hợp của CityDists, thì đó cũng có thể là bogging xuống bộ nhớ như mảng đang nhận được tái tạo mỗi khi một lớp mới CityDists được tạo ra. Hãy thử khai báo mảng của bạn như tĩnh và khởi tạo nó trong constructor tĩnh:

private static City[] cc = new City[10000]; 

static CityDists() 
{ 
    cc[2].name = "Lae, Papua New Guinea"; cc[2].lat = 123; cc[2].lon = 123; 
    cc[3].name = "Rabaul, Papua New Guinea"; cc[3].lat = 123; cc[3].lon = 123; 
    cc[4].name = "Angmagssalik, Greenland"; cc[4].lat = 123; cc[4].lon = 123; 
    cc[5].name = "Angissoq, Greenland"; cc[5].lat = 123; cc[5].lon = 123; 
... 
1

Nếu bạn muốn tránh các phân tích cú pháp XML và bộ nhớ trên cao, bạn có thể sử dụng một tập tin văn bản đơn giản để lưu trữ dữ liệu của bạn và sử dụng chuỗi Net tokenizer chức năng để phân tích các mục ví dụ sử dụng String.Chia()

Bạn cũng có thể tải tệp một phần để giữ mức tiêu thụ bộ nhớ thấp. Ví dụ: bạn chỉ tải k trong số n dòng của tệp. Trong trường hợp bạn cần truy cập một bản ghi nằm ngoài phân đoạn k được tải hiện tại, hãy tải các phân đoạn k thích hợp. Bạn có thể làm theo cách cũ của trường học hoặc thậm chí sử dụng công cụ sắp xếp theo thứ tự ưu tiên từ .Net

1

Sử dụng tệp như XML hoặc tệp phân tách đơn giản sẽ là cách tiếp cận tốt hơn như những người khác đã chỉ ra. Tuy nhiên, tôi cũng có thể đề xuất một thay đổi khác để cải thiện việc sử dụng bộ nhớ.

Something như thế này (mặc dù việc tải thực tế nên được thực hiện sử dụng một tập tin bên ngoài): -

public struct City 
{ 
    public string name; 
    public string country; 
    public double lat; 
    public double lon; 
} 

private static City[] cc = new City[10000]; 
static CityDists() 
{ 
    string[] countries = new string[500]; 
    // Replace following with loading from a "countries" file. 
    countries[0] = "Papua New Guinea"; 
    countries[1] = "Greenland"; 

    // Replace following with loading from a "cities" file. 
    cc[2].name = "Lae"; cc[2].country = contries[0]; cc[2].lat = 123; cc[2].lon = 123; 
    cc[3].name = "Rabaul"; cc[3].country = countries[0]; cc[3].lat = 123; cc[3].lon = 123;    
    cc[4].name = "Angmagssalik"; cc[4].country = countries[1]; cc[4].lat = 123; cc[4].lon = 123;    
    cc[5].name = "Angissoq"; cc[5].country= countries[1]; cc[5].lat = 123; cc[5].lon = 123;    
} 

Điều này làm tăng kích thước của cấu trúc nhẹ nhưng làm giảm bộ nhớ sử dụng bởi tên nước trùng lặp signficantly.

1

Tôi nghe thấy sự thất vọng của bạn. Chạy mã của bạn mà không có trình gỡ rối, nó sẽ hoạt động tốt. Tôi đang tải 2 mảng dưới 3 giây, mỗi mảng có hơn 100.000 phần tử. Trình gỡ lỗi báo cáo "Hết bộ nhớ", đơn giản là không đúng.

Oh và bạn chính xác về hiệu quả. Việc tải cùng một thông tin từ một tệp XML đã mất hơn 30 giây trên điện thoại.

Tôi không biết ai đang trả lời câu hỏi của bạn nhưng họ thực sự nên gắn bó với tiếp thị.

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