2010-11-06 10 views
10

Mam pytanie, które jest tak proste, że nie mogę uwierzyć, że nie potrafię na nie odpowiedzieć. Ale proszę.Używanie dużej tablicy statycznej w języku C# (Silverlight na Windows Phone 7)

Mam dużą listę statyczną (miast, szerokości i długości geograficznej), którą chcę użyć w mojej aplikacji Windows Phone 7 Silverlight. Jest ich około 10 000. Chciałbym statycznie osadzić te dane w mojej aplikacji i uzyskać do niej dostęp w postaci tablicy (muszę cyklicznie przeglądać całą listę w kodzie).

Co będzie moim najskuteczniejszym sposobem przechowywania tego? Jestem trochę starej szkoły rodzaju, więc liczyć najszybszą drogę do zrobienia byłoby:

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

a potem ...

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

Jednak to włóczędzy się z " out of memory "Błąd zanim kod faktycznie zostanie uruchomiony (zakładam, że sam kod zakończył się zbyt dużym obciążeniem pamięci).

Wszystko, co czytam w Internecie, informuje mnie, że należy użyć zasobu lub pliku XML, a następnie przekształcić go w instancje klasy. Ale czy to naprawdę może być tak szybkie, jak użycie struktury? Czy XML nie będzie analizował wieku?

Myślę, że jestem w stanie napisać kod tutaj - po prostu nie jestem pewien, od czego najlepiej zacząć. Interesuje mnie szybkość ładowania i (co ważniejsze) dostęp do czasu pracy bardziej niż cokolwiek innego.

Każda pomoc bardzo doceniona - pierwsze pytanie tutaj, więc mam nadzieję, że nie zrobiłem nic z kościołem.

Chris

+0

Witaj Chris, jaka objętość danych w sumie? Ile pamięci w systemie i jest dużo za darmo? Zakładam, że testujesz na emu. Ciekawe, że nie przeszkadza mi, że pytam, jakie jest źródło danych. Szukałem również opcji dla danych miejskich. –

+0

Dla odniesienia 100k prostych danych XML można załadować z XAP za pomocą XDocument, wyświetlonych w polu listy i zapisanych w odizolowanym magazynie w ciągu 0,5 sekundy na urządzeniu 650MHz. –

+12

Hi Mick - Korzystam z danych pochodzących z http://www.partow.net/miscellaneous/airportdatabase/index.html. Jest tam trochę śmieci, które usunąłem i przekonwertowałem szerokość i długość geograficzną na metrykę - jeśli jest jakiś sposób, aby się ze mną skontaktować, chętnie podzielę się końcowym wynikiem (jest to arkusz kalkulacyjny Excela teraz). Zajrzę do XDocument - to brzmi łatwo wystarczająco szybko, na co czekam! –

Odpowiedz

1

przypadku ładowania dokumentu XML z XAP działa dla Ciebie ..

Oto projekt Zamieściłem wykazując ładowanie z doc xml z XAP za pomocą XDocument/LINQ i databinding do listbox dla odniesienia.

binding a Linq datasource to a listbox

+0

Działa to świetnie, wielkie dzięki. Skończyłem czyszczenie danych i mam 3000 lub więcej miast o szerokości i długości geograficznej - prosimy o kontakt, jeśli chcesz! –

+0

yw:) ... Zapisałem link, ty :) –

3

10000 elemencie nie powinno zabraknąć pamięci, ale po prostu, aby upewnić się, chciałbym najpierw spróbować obracając swoją struct do klasy tak, że używa sterty zamiast stosu. Istnieje duże prawdopodobieństwo, że spowoduje to usunięcie błędów pamięci.

Plik XML przechowywany w odizolowanym magazynie może być dobrym rozwiązaniem, jeśli dane będą aktualizowane od czasu do czasu. Można pobrać miasta z usługi sieci Web i serializować te klasy do magazynu aplikacji w odosobnionym miejscu, gdy tylko zostaną zaktualizowane.

Zauważam również w próbkach kodu, że tablica cc nie jest zadeklarowana jako statyczna. Jeśli masz kilka instancji CityDists, to może to również powodować wyczerpywanie pamięci, ponieważ tablica jest ponownie tworzona za każdym razem, gdy tworzona jest nowa klasa CityDists. Spróbuj deklarując swoją tablicę jako statyczne i inicjowanie go w statycznym konstruktorze:

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

Jeśli chcesz uniknąć analizowania XML i narzut pamięci, można użyć pliku tekstowego do przechowywania danych i korzystać z funkcji ciąg .Net tokenizer do analizowania zapisów np użyj String.Split()

Można również załadować plik częściowo, aby zmniejszyć zużycie pamięci. Na przykład ładujesz tylko k z n wierszy pliku. Jeśli potrzebujesz dostępu do rekordu spoza aktualnie ładowanych segmentów k, załaduj odpowiednie k segmentów. Można to zrobić w starym stylu, a nawet użyć fantazyjnego materiału serializacyjnego z .Net

1

Używanie pliku takiego jak XML lub prosty plik rozdzielany byłby lepszym rozwiązaniem, jak wskazali inni. Czy mogę jednak zaproponować kolejną zmianę, aby poprawić wykorzystanie pamięci.

Coś takiego (chociaż rzeczywista ładowania powinny być wykonane przy użyciu zewnętrznego pliku): -

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

To zwiększa rozmiar struktury nieznacznie ale zmniejsza pamięć używaną przez zduplikowanych nazw państw signficantly.

1

Słyszę twoją frustrację. Uruchom swój kod bez debuggera, powinien działać dobrze. Ładuję 2 tablice w czasie poniżej 3 sekund, z których każdy zawiera ponad 100 000 elementów. Debugger zgłasza "Out of Memory", co nie jest prawdą.

Och i masz rację co do wydajności. Ładowanie tych samych informacji z pliku XML zajęło ponad 30 sekund na telefonie.

Nie wiem, kto odpowiadał na twoje pytanie, ale oni naprawdę powinni pozostać przy marketingu.

Powiązane problemy