2010-11-06 9 views
10

Ho una domanda così semplice che non posso credere di non poter rispondere da solo. Ma eccoti.Utilizzo di un array statico di grandi dimensioni in C# (Silverlight su Windows Phone 7)

Ho una lista statica di grandi dimensioni (di città, latitudini e longitudini) che voglio usare nell'applicazione Silverlight di Windows Phone 7. Ce ne sono circa 10.000. Mi piacerebbe incorporare questi dati staticamente nella mia applicazione e accedervi in ​​un array (ho bisogno di scorrere l'intero elenco in codice abbastanza regolarmente).

Quale sarà il mio mezzo più efficace per archiviare questo? Sono un po 'di una vecchia scuola sorta, in modo da calcolai il modo più veloce per farlo sarebbe:

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

e poi ...

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

Tuttavia, questo barboni fuori con una " "Memoria insufficiente" prima che il codice venga effettivamente eseguito (presumo che il codice stesso sia finito per essere caricato troppo in memoria).

Tutto ciò che ho letto online mi dice di usare una risorsa o un file XML e poi di deserializzare ciò in istanze di una classe. Ma può essere davvero veloce come usare una struttura? L'XML non impiegherà secoli per essere analizzato?

Penso di essere in grado di scrivere il codice qui - non sono sicuro di quale sia l'approccio migliore per iniziare. Sono interessato alla velocità di caricamento e (più importante) l'accesso al tempo di esecuzione più di ogni altra cosa.

Qualsiasi aiuto molto apprezzato - prima domanda qui, quindi spero di non aver fatto niente con i capelli.

Chris

+0

Ciao Chris, Quale volume di dati in totale? Quanta memoria è presente sul tuo sistema ed è gratuita? Suppongo che tu stia provando sull'emù. Anche curioso se non ti dispiace che mi chieda quale sia la fonte dei dati. Ho anche esaminato le opzioni per i dati della città. –

+0

Per il riferimento 100k di semplici dati XML possono essere caricati da XAP utilizzando XDocument, visualizzati in una lista e salvati in una memoria isolata in 0,5 secondi su un dispositivo 650Mhz. –

+12

Ciao Mick - Sto usando i dati che provengono da http://www.partow.net/miscellaneous/airportdatabase/index.html. C'è un po 'di spazzatura lì dentro che ho spogliato e ho convertito la latitudine e la longitudine in metrica - se c'è un modo in cui puoi metterti in contatto con me sarei felice di condividere il risultato finale (è in un foglio di calcolo di Excel proprio adesso). Vedrò XDocument - sembra abbastanza veloce per quello che sto cercando! –

risposta

1

Se il caricamento di un documento XML dal XAP funziona per voi ..

Ecco un progetto che ho postato dimostrando carico della doc XML da l'XAP tramite XDocument/LINQ e l'associazione dati ad una listbox come riferimento.

binding a Linq datasource to a listbox

+0

Funziona alla grande, molte grazie. Ho terminato la pulizia dei dati e ho 3000 o più città con latitudini e longitudini - per favore mettiti in contatto se lo vuoi! –

+0

yw:) ... Ho salvato il collegamento, ty :) –

3

10.000 le strutture non devono esaurire la memoria, ma solo per assicurarsi che, vorrei provare prima trasformare il vostro struct in una classe in modo che utilizza l'heap al posto della pila. C'è una forte possibilità che farlo risolverà gli errori di memoria insufficiente.

Un file XML archiviato in una memoria isolata potrebbe essere un buon metodo se i dati verranno aggiornati anche di tanto in tanto. È possibile estrarre le città da un servizio Web e serializzare tali classi nell'archivio applicazioni in una memoria isolata ogni volta che vengono aggiornate.

Inoltre, ho notato nei campioni di codice che l'array cc non è dichiarato statico. Se si dispone di alcune istanze di CityDists, potrebbe anche verificarsi un blocco della memoria poiché la matrice viene ricreata ogni volta che viene creata una nuova classe CityDists. Prova dichiarando l'array come qualcosa di statico e l'inizializzazione nel costruttore statico:

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

Se si vuole evitare il parsing XML e sovraccarico di memoria, è possibile utilizzare un file di testo per la memorizzazione dei dati e utilizzare la stringa .Net tokenizer funzioni per analizzare le voci per esempio usare String.Split()

È anche possibile caricare parzialmente il file per mantenere basso il consumo di memoria. Ad esempio, carichi solo k di n righe del file. Nel caso in cui sia necessario accedere a un record che si trova al di fuori dei segmenti k attualmente caricati, caricare i segmenti k appropriati. Potresti farlo alla vecchia maniera o usare anche le fantasiose opzioni di serializzazione da .Net

1

Utilizzare un file come XML o un file delimitato semplice sarebbe un approccio migliore come altri hanno sottolineato. Tuttavia, posso anche suggerire un altro cambiamento per migliorare l'uso della memoria.

Qualcosa di simile (anche se il carico effettivo deve essere fatto utilizzando un file esterno): -

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

Questo aumenta la dimensione della struttura leggermente, ma riduce la memoria utilizzata dai nomi dei paesi duplicati signficantly.

1

Ho sentito la tua frustrazione. Esegui il tuo codice senza il debugger, dovrebbe funzionare bene. Sto caricando 2 array in meno di 3 secondi, ciascuno con oltre 100.000 elementi. Debugger segnala "Memoria insufficiente", che semplicemente non è il caso.

Oh e hai ragione sull'efficienza. Il caricamento delle stesse informazioni da un file XML richiedeva più di 30 secondi al telefono.

Non so chi rispondesse alla tua domanda ma in realtà dovrebbero attenersi al marketing.

Problemi correlati