¿Forma práctica de almacenar una cantidad de datos "razonablemente grande" que casi nunca cambia?

13

Piense en términos de tablas de búsqueda precalculadas o algo así. ¿En qué punto tiene más sentido usar una base de datos en lugar de valores de codificación en mi aplicación? Los valores no van a cambiar, y están muy bien separados de los desarrolladores de mantenimiento. 100 valores, 1k, 10k, 100k? Quiero almacenar unos 40k valores. En este momento es una switchdeclaración generada por una máquina (de la cual VS2010 no está contento).

editar:

Si alguien tiene curiosidad, así es como me acerqué a esto: mis datos se podían almacenar en dos matrices flotantes de 100k elementos, así que eso fue lo que hice. Me llevó unos 20 segundos generar los datos, así que lo hice una vez y los serialicé en un recurso incrustado con un BinaryFormatter. El desempaquetado de los datos lleva aproximadamente 5 milisegundos al inicio de la aplicación, y supera la implementación de la base de datos que estaba reemplazando (estos valores codificados se almacenaron allí antes) en casi 45,000x.

Bryan Boettcher
fuente

Respuestas:

5

Mi sugerencia es mantener los datos en un archivo o tabla de base de datos. Si la velocidad no es un problema, consulte el archivo o la base de datos (la base de datos es mejor) en tiempo de ejecución. Si la memoria no es un problema, pero desea algo de velocidad, cargue los datos en la memoria cuando se inicie el programa. En C #, puede usar una matriz, listar o (mejor opción) una tabla hash y tener un método para devolver los datos que necesita en tiempo de ejecución (es decir, getDataValue (string keyToValue)).

Le recomendaría que no use la instrucción switch ya que sería muy difícil de mantener y daría lugar a una gran huella de exe.

Hash-table, por ejemplo, http://support.microsoft.com/kb/309357

adam f
fuente
En última instancia, esto es lo que hice: verifique mi publicación actualizada.
Bryan Boettcher
1
+1 para la sugerencia de la base de datos. Las bases de datos están hechas para almacenar grandes volúmenes de datos y le permite recuperarlos muy rápidamente.
NoChance
Consulte stackoverflow.com/questions/301371/… sobre por qué es mejor usar un diccionario para esto en lugar de una tabla hash. YMMV
Chris McKee
6

Personalmente, estoy de acuerdo en almacenar cualquier cantidad de datos, codificados en la aplicación, hasta que no haya necesidad de modificarlos para una implementación o revisión en particular.

Sin embargo, almacenar y acceder a datos usando la declaración de cambio de C # es una práctica bastante mala, ya que en estrecha relación con el almacenamiento de datos y el modelo de acceso a datos e implica solo un método de acceso de método (por parámetro de cambio).

Preferiría almacenar datos en un Hashtable o Diccionario, y proporcionar clases separadas para recuperar los datos, y llenar una vez de Diccionarios de búsqueda.

Recientemente, he encontrado bastante conveniente implementar DSL pequeño para especificar reglas comerciales ( interfaz fluida para SiteMap o el método "calc" de verificación de preguntas de entrevista de calculadora de impuestos para la defensa de reglas) y luego proporcionar un objeto separado para consultar estas reglas. Esta técnica se aplicaría bien para el caso de cambio de escenario.

Una de las ventajas de dicha descomposición es que puede implementar varias Vistas en sus datos, sin tocar el blob de XXXk líneas, que define esos datos.

Valera Kolupaev
fuente
He extendido la respuesta con algunos ejemplos.
Valera Kolupaev
2

Una declaración de cambio de línea de 40k es un poco cuestionable. Supongo que aún necesita realizar operaciones de consulta, ¿verdad? ¿Has intentado encapsular los datos? Luego use LINQ para realizar operaciones de consulta en la colección para probar el rendimiento. Obtenga algunos tiempos concretos ejecutando pruebas unitarias con un temporizador como StopWatch . Entonces, si crees que podría funcionar. Vea si el rendimiento es aceptable para los usuarios.

P.Brian.Mackey
fuente
2

He tenido un requisito como este dos veces. Las aplicaciones fueron diseñadas para ser independientes sin necesidad de configuración / acceso a la base de datos. En ambos casos utilicé archivos XML para almacenar los datos. En el primero, que estaba en el Marco 2.0, utilicé las llamadas de análisis XML de estilo antiguo para buscar datos. Para el más nuevo, en el Framework 3.5, usé LINQ to XML para encontrar lo que necesitaba. En ambos casos, el acceso a los datos se encapsuló en clases.

jfrankcarr
fuente
1

La clave aquí es asegurarse de que su interfaz pública encapsule su implementación, pero esa no es su pregunta y no hay razón para pensar que no lo haya hecho. Más allá de eso, es solo una cuestión de rendimiento versus dolor (y las diferencias de rendimiento pueden no valer la pena). Como solución práctica, para el problema de VS 2010, siempre puede dividir la declaración del caso en una jerarquía de declaraciones de casos: el nivel superior podría llamar a uno de los otros 10 métodos, cada uno con una declaración de caso de 4000 casos, por ejemplo. Puede poner cada uno de los 10 en su propio archivo si fuera necesario. Un poco feo, pero de todos modos estás generando código.

En cuanto al número para cambiar a un DB, solo cuando no se usa un DB se convierte en un problema.

psr
fuente
Aprecio la idea de que mi interfaz encapsula la implementación: ciertamente lo hace. La funcionalidad se expone a través de un GetValuesForInputmétodo de tipo, y mi declaración masiva está oculta en la implementación.
Bryan Boettcher
1

Podría usar algo como SQL Compact. Ponga los datos en una tabla y deje el archivo DB en el proyecto. Las tablas son más adecuadas para esa cantidad de datos que una declaración de cambio.

Morgan Herlocker
fuente
1

Creo que la palabra clave aquí es 'apenas'

Si los datos nunca cambian, por ejemplo, valores matemáticos precalculados, constantes de color y similares, entonces, seguro, siempre que el tamaño sea manejable para usted, manténgalo en el código. Solo tenga en cuenta que si el rendimiento es un problema, las declaraciones de caso / cambio serán muy lentas en comparación con otras opciones.

Si los datos casi nunca cambian, por ejemplo, códigos de área telefónica, límites nacionales y similares, probablemente buscaría mantener los datos externamente de alguna manera. Particularmente si comenzó a llegar a ser más de un par de docenas de valores.

Gran maestro B
fuente
1
Depende de qué tan bueno sea el compilador. Una declaración de caso en Delphi puede ser extremadamente eficiente.
Loren Pechtel
1

Si almacena grandes volúmenes de datos en su aplicación, entonces su programa puede cargar más lentamente y puede exponer el código al riesgo en caso de que alguien pueda jugar con los archivos binarios o ejecutables.

Además, si el programa se edita muchas veces, quién sabe, podría introducir errores al escribir mal un número por error o como resultado del comando de cambio.

Puede ser que en el futuro alguien solicite ejecutar consultas sobre los datos, por ejemplo, alguien puede pedir el promedio de una columna, en cuyo caso tendrá que cambiar su aplicación y agregar un método para calcular cada consulta que su usuario haga. con, luego siga todos los pasos para promocionar su código a producción. Esto realmente no es bueno.

Separar datos y código es una buena práctica, especialmente si los datos son grandes.

Ninguna posibilidad
fuente