Modo pratico per archiviare una quantità "ragionevolmente grande" di dati che non cambia quasi mai?


13

Pensa in termini di tabelle di ricerca pre-calcolate o altro. A che punto ha più senso usare un database invece di valori hardcoding nella mia applicazione? I valori non cambieranno e sono ben separati dagli sviluppatori di manutenzione. 100 valori, 1k, 10k, 100k? Voglio memorizzare circa 40.000 valori. Al momento è switchun'affermazione generata dalla macchina (di cui VS2010 non è scontento).

modificare:

Se qualcuno è curioso, ecco come mi sono avvicinato a questo: i miei dati erano memorizzabili in due array float da 100k elementi, quindi è quello che ho fatto. Ci sono voluti circa 20 secondi per generare i dati, quindi l'ho fatto una volta e li ho serializzati su una risorsa integrata con un BinaryFormatter. La decompressione dei dati richiede circa 5 millisecondi all'avvio dell'applicazione e supera l'implementazione del database che stavo sostituendo (questi valori codificati in precedenza erano archiviati lì in precedenza) di quasi 45.000 volte.

Risposte:


5

Il mio consiglio è di conservare i dati in una tabella di file o database. Se la velocità non è un problema, eseguire una query sul file o sul database (il database è migliore) in fase di esecuzione. Se la memoria non è un problema, ma si desidera una certa velocità, quindi caricare i dati in memoria all'avvio del programma. In C # è possibile utilizzare e array, elenco o (opzione migliore) una tabella hash e disporre di un metodo per restituire i dati necessari in fase di esecuzione (ad esempio getDataValue (string keyToValue)).

Consiglierei di non usare l'istruzione switch in quanto sarebbe molto difficile da mantenere e comporterebbe un ingombro di exe di grandi dimensioni.

Hash-table, ad esempio http://support.microsoft.com/kb/309357


Questo alla fine è quello che ho fatto: controlla il mio post aggiornato.
Bryan Boettcher

1
+1 per il suggerimento del database. I database sono creati per archiviare grandi volumi di dati e consentono di recuperarli molto rapidamente.
NoChance,

Vedi stackoverflow.com/questions/301371/… sul perché è meglio usare un dizionario per questo piuttosto che una tabella hash. YMMV
Chris McKee,

6

Personalmente, sono OK per archiviare qualsiasi quantità di dati, hardcoded nell'applicazione, fino a quando non è necessario modificarlo per una particolare distribuzione o hotfix.

Tuttavia, l'archiviazione e l'accesso ai dati utilizzando l'istruzione switch C # è piuttosto una pratica errata, poiché in coppie strettamente legate al modello di archiviazione e accesso ai dati e implica un solo metodo di accesso al metodo (per parametro switch).

Preferirei archiviare i dati in un hashtable o in un dizionario e fornire classi separate per il recupero dei dati e il popolamento di una volta dei dizionari di ricerca.

Di recente, ho trovato piuttosto conveniente implementare un piccolo DSL per specificare le regole di business ( interfaccia fluida per SiteMap o metodo di calcolo delle domande di intervista con il calcolatore delle tasse per la definizione delle regole) e quindi fornire un oggetto separato per l'interrogazione di queste regole. Questa tecnica si applicherebbe bene per lo scenario del caso switch.

Uno dei vantaggi di questa scomposizione è che puoi implementare un numero di visualizzazioni sui tuoi dati, senza toccare il BLOB di linee XXXk, che definisce tali dati.


Ho esteso la risposta con alcuni esempi.
Valera Kolupaev,

2

Un'istruzione switch di linea 40k è un po 'discutibile. Presumo che tu debba ancora eseguire le operazioni di query, giusto? Hai provato a incapsulare i dati? Quindi utilizzare LINQ per eseguire operazioni di query sulla raccolta per testare le prestazioni. Ottieni dei tempi concreti eseguendo test unitari con un timer come StopWatch . Quindi, se pensi che potrebbe funzionare. Verifica se le prestazioni sono accettabili per gli utenti.


2

Ho avuto un requisito come questo due volte. Le applicazioni sono state progettate per essere autonome senza necessità di impostazione / accesso al database. In entrambi i casi ho usato i file XML per archiviare i dati. Nel primo, che era sul Framework 2.0, ho usato le chiamate di analisi XML vecchio stile per cercare i dati. Per quello più recente, sul Framework 3.5, ho usato LINQ to XML per trovare ciò di cui avevo bisogno. In entrambi i casi, l'accesso ai dati è stato incapsulato in classi.


1

La cosa chiave qui è assicurarsi che la tua interfaccia pubblica incapsuli la tua implementazione, ma questa non è la tua domanda e non c'è motivo di pensare di non averlo fatto. Oltre a ciò, è solo una questione di prestazioni vs dolore (e potrebbe non valere la pena preoccuparsi delle differenze di prestazioni). Come soluzione pratica, per il problema VS 2010, è sempre possibile suddividere l'istruzione case in una gerarchia di istruzioni case: il livello superiore potrebbe chiamare uno degli altri 10 metodi, ciascuno con un'istruzione case di 4000 casi, ad esempio. Puoi mettere ognuno dei 10 nel suo file se dovessi. Un po 'brutto, ma stai comunque generando codice.

Per quanto riguarda il numero di passare a un DB, è solo quando non si utilizza un DB diventa un problema.


Apprezzo il pensiero che la mia interfaccia incapsuli l'implementazione: sicuramente lo fa. La funzionalità è esposta con un GetValuesForInputmetodo di tipo e la mia enorme affermazione è nascosta nell'implementazione.
Bryan Boettcher,

1

Potresti usare qualcosa come SQL Compact. Inserisci i dati in una tabella e lascia il file DB nel progetto. Le tabelle sono più adatte per quella quantità di dati rispetto a un'istruzione switch.


1

Penso che la parola chiave qui sia "appena"

Se i dati non cambiano mai , ad esempio valori matematici precalcolati, costanti di colore e simili, allora, purché la dimensione sia gestibile per te, tienili nel codice. Basta essere consapevoli del fatto che se le prestazioni sono un problema, le istruzioni case / switch saranno molto lente rispetto ad altre opzioni.

Se i dati non cambiano quasi mai, ad esempio prefissi telefonici, confini nazionali e simili, probabilmente cercherò di mantenere i dati esternamente in qualche modo. Soprattutto se ha iniziato a diventare più di una dozzina di valori.


1
Dipende da quanto è buono il compilatore. Una dichiarazione del caso in Delphi può essere estremamente efficiente.
Loren Pechtel,

1

Se memorizzi grandi volumi di dati nella tua applicazione, il tuo programma potrebbe caricarsi più lentamente e potresti esporre il codice al rischio nel caso in cui qualcuno potesse giocare con i file binari o eseguibile.

Inoltre, se il programma viene modificato più volte, chissà, potresti introdurre errori digitando erroneamente un numero per errore o come risultato del comando change.

Potrebbe essere in futuro che qualcuno chieda di eseguire query sui dati, ad esempio qualcuno potrebbe chiedere la media di una colonna, nel qual caso dovrai cambiare la tua applicazione e aggiungere un metodo per calcolare ogni query che il tuo utente presenta con, quindi segui tutti i passaggi per promuovere il codice in produzione. Questo non è davvero buono.

La separazione di dati e codice è una buona pratica specialmente se i dati sono di grandi dimensioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.