2012-03-15 11 views
6

Tengo una aplicación web que usa Guids como PK en la base de datos para un objeto Employee y un objeto Association.Transferencia de muchos objetos con IDs de guía al cliente

Una página en mi aplicación devuelve una gran cantidad de datos que muestran todas las asociaciones de las que todos los empleados pueden formar parte.

Así que ahora mismo, estoy enviando al cliente esencialmente un montón de objetos que se parecen:

{assocation_id: guid, employees: [guid1, guid2, ..., guidN]} 

Resulta que muchos empleados pertenecen a muchas asociaciones, así que voy a enviar por el mismo GUID para esos empleados una y otra vez en estos diferentes objetos. Por ejemplo, es posible que envíe 30,000 guids totales en todas las asociaciones en algunos casos, de los cuales solo hay 500 empleados únicos.

me pregunto si vale la pena que me la construcción de una especie de índice de búsqueda que también le envío al cliente como

{ 1: Guid1, 2: Guid2 ... } 

y la sustitución de todos los GUID de los objetos que envío abajo con esos enteros,

o si simplemente gzipping la respuesta lo comprimirá lo suficiente como para que este esfuerzo adicional no valga la pena?

Nota: no se deje atrapar por los detalles de si debería enviar 30,000 datos o no; esta no es mi elección y no hay nada que pueda hacer al respecto (y también puedo no cambie Guids a ints o longs en el DB).

+0

¿Por qué no utiliza el método Linq Distinct()? ¿O usar DISTINCT en la consulta dbase? –

+0

¿Por qué no enviar la lista de * asociación * por * empleados? – ydroneaud

+0

Por más razones que el ancho de banda de respuesta, separaría los recursos anidados para este caso como usted sugiere. Puede usar solicitudes ajax separadas para ellos, o cargarlas de forma diferida a pedido. – aceofspades

Respuesta

0

Entonces, ¿qué está tratando de lograr es la compresión del diccionario, ¿verdad? http://en.wikibooks.org/wiki/Data_Compression/Dictionary_compression Lo que obtendrá en lugar de las guías que tienen una longitud de 16 bytes es int y tiene 4 bytes de longitud. Y obtendrás un diccionario lleno de pares de valores clave que asociarán cada guid a algún valor int, ¿verdad? Disminuirá el tiempo de transferencia cuando haya muchos objetos con la misma identificación utilizada. Pero gastará tiempo de CPU antes de la transferencia para comprimir y después de la transferencia para descomprimir. Entonces, ¿cuál es la cantidad de datos que transfiere? ¿Es mb/gb/tb? ¿Y hay alguna buena razón para comprimirlo antes de enviarlo?

+0

Los enteros pequeños ** serializados como JSON ** ocupan menos lugar que la mitad del lugar de GUID y se agitan menos que GUID. Compare '" {7EDBB957-5255-4b83-A4C4-0DF664905735} "' o '" 7EDBB95752554b83A4C40DF664905735 "' con '499' (34 o 3 caracteres). – Oleg

6

Su escribió al final de su pregunta lo siguiente

Nota: por favor, no quedar atrapados en los detalles de si debería ser el envío de piezas de hasta 30.000 datos o no - esto es no es mi elección y no hay nada que pueda hacer al respecto (y tampoco puedo cambiar Guids a ints o longs en la base de datos).

Creo que es su problema principal. Si no resuelve el problema principal, podrá reducir el tamaño de los datos transferidos a 10 veces, por ejemplo, pero aún no resuelve el problema principal. Pensemos en la pregunta: ¿Por qué se deben enviar tantos datos al cliente (al navegador web)?

Los datos del lado del cliente son necesarios para mostrar información para el usuario. El monitor no es tan grande para mostrar 30,000 en total en una página. Ningún usuario puede captar tanta información. Así que estoy seguro de que muestra solo una pequeña parte de la información. En el caso, debe enviar solo la pequeña parte de la información que visualiza.

No describe cómo se usarán las guías en el lado del cliente. Si necesita la información durante la edición de filas, por ejemplo. Puede transferir los datos solo cuando el usuario comienza a editar. En el caso de que necesite transferir los datos solo para una asociación.

Si necesita mostrar las guías directamente, entonces no puede mostrar toda la información a la vez. Para que pueda envíe la información de una sola página al. Si el usuario comienza a desplazarse o iniciar el botón "siguiente página" puede enviar la siguiente porción de datos. En la forma en que realmente puede reducir drásticamente el tamaño de los datos transferidos.

Si usted tiene ninguna posibilidad de rediseñar la parte de aplicación puede implementar su sugerencia original: mediante la sustitución de GUID "{7EDBB957-5255-4b83-A4C4-0DF664905735}" o "7EDBB95752554b83A4C40DF664905735" al número como 123 se reduce el tamaño de los GUID de 34 caracteres a 3. Si se quiere enviar adicionalmente matriz de elementos "GUID de mapeo" como

123:"7EDBB95752554b83A4C40DF664905735", 

se puede reducir el tamaño original de 30.000 datos * 34 = 1.020.000 (1 MB) a 300 * 39 + 30000 * 3 = 11700 + 90000 = 101700 (100 KB). Entonces puede reducir el tamaño de los datos en 10 veces. El uso de la compresión de datos dinámicos en el servidor web puede reducir el tamaño de los datos de manera adicional.

En cualquier caso, debe examinar por qué su página es tan lenta. Si el programa funciona en LAN, entonces la transferencia de hasta 1MB de datos puede ser lo suficientemente rápida. Probablemente la página sea lenta durante la colocación de los datos en la página web. Me refiero a lo siguiente. Si modifica algún elemento en la página, la posición de debe recalcularse todos los elementos existentes. Si trabajas primero con objetos DOM desconectados y luego colocas toda la porción de datos en la página, puedes mejorar el rendimiento dramáticamente. No publicas en la pregunta qué tecnología utilizas en tu aplicación web, así que no incluyo ningún ejemplo. Si usa jQuery, por ejemplo, podría dar un ejemplo que aclare más lo que quiero decir.

+0

A veces el desarrollador recibe requisitos que no pueden cambiar, a pesar de la lógica de un enfoque alternativo. Creo que Davis es bastante claro al indicar que esa es la situación aquí. – Random

+0

@Random: Si se puede cambiar el formato de la respuesta del servidor como reemplazarla con el índice en la matriz '[Guid1, Guid2, ...]', entonces uno * do * puede cambiar el protocolo entre la comunicación entre el servidor y el cliente. Sabemos muy poca información sobre el problema. Quería mencionar que la transferencia de 30,000 guids totales para una página es definitivamente * demasiado como para mostrar la información existente en la página *. Supongo que si uno analiza el problema más bajo el aspecto uno puede reducir el tamaño de los datos transferidos en muchas ocasiones. – Oleg

+0

No estoy necesariamente en desacuerdo. Y la información en tu respuesta es útil. Solo estoy diciendo que dado que Davis parece entender esto también, limita la aplicabilidad de su respuesta a su problema específico. – Random

2

El índice de búsqueda que propone no es más que un esquema de compresión "personalizado". Como amdmax indicó, esto aumentará su rendimiento si tiene muchos de los mismos GUID, pero también lo hará gzip.

En mi humilde opinión, el esfuerzo extra de escribir la codificación personalizada no valdrá la pena.

Oleg afirma correctamente que valdría la pena obtener los datos solo cuando el usuario lo necesite. Pero esto, por supuesto, depende de sus requisitos específicos.

1

si simplemente gzipping la respuesta lo comprimirá lo suficiente como para que este esfuerzo adicional no valga la pena?
La respuesta es: Sí, será.

Al comprimir los datos se eliminarán las partes redundantes lo mejor posible (según el algoritmo) hasta la descompresión.

Para estar seguro, solo envíe/genere los datos descomprimidos y comprimidos y compare los resultados. Puede contar los GUID duplicados para calcular qué tan grande sería su bloque de datos con el método de compresión del diccionario. Pero supongo que gzip será mejor porque también puede comprimir los elementos sintácticos como llaves, dos puntos, etc. dentro de su objeto de datos.

+0

Después de hacer algunas pruebas, resulta que se necesita un 50% más de datos para transferir todo el gzip'd que la compresión del diccionario. Desafortunadamente bastante sustancial –

0

No sé lo dinámico que es sus datos, pero me

  • en una primera llamada de enviar dos directorios/diccionarios ID abreviados de mapeo para GUIDS largos, uno de sus asociaciones y por sus empleados, por ejemplo, {1: AssoGUID1, 2: AssoGUID2, ...} y {1: EmpGUID1, 2: EmpGUID2, ...}. Estos directorios también pueden contener información adicional sobre las instancias de Asociaciones y Empleados; Sospecho que no solo muestra los GUID

  • en llamadas subsiguientes simplemente envíe el índice de Empleados por Asociación {1: [2,4,5], 3: [2,4], ...}, la clave siendo la identificación corta de la asociación y los identificadores en el valor de la matriz, los identificadores cortos de los empleados. Dada su descripción construcción del índice inverso: Empleado a las asociaciones pueda dar un mejor resultado tamaño conveniente (pero mayor procesamiento)

Luego todo se debe a su arrays asociativos manipulaciones que es sencillo en JS.

Nuevamente, si sus datos son (muy) dinámicos en el lado del servidor, los dos directorios pronto quedarán obsoletos y mantener la sincronización puede costarle mucho.

0

Me gustaría empezar por responder a las siguientes preguntas:

¿Cuáles son los requisitos de rendimiento? ¿Hay requisitos de tamaño? Requisitos de velocidad? ¿Cuál es el rendimiento mínimo que realmente se necesita?

¿Cuáles son las métricas de rendimiento actuales? ¿Qué tan lejos estás de los requisitos?

Caracterizó los datos como posiblemente repeticiones en su mayoría. ¿Es ese el caso normal? Si no, ¿qué es?

Las 2 opciones enumeradas anteriormente suenan razonables y triviales para implementar. Intenta crear una tabla de búsqueda y ver qué mejoras de rendimiento obtienes en las consultas reales. Intente comprimir los resultados (con búsquedas y sin ellos) y vea qué ganancias obtiene.

Según mi experiencia, si no está MUY lejos del objetivo, los requisitos de rendimiento a menudo son de prueba y error.

Si esas opciones no lo acercan a los requisitos, me gustaría dar un paso atrás y ver si los requisitos son razonables en el tiempo que tiene para resolver el problema.

Lo que debe hacer a continuación depende de los objetivos de rendimiento que faltan. Si se trata de un tamaño, estás empezando a estar limitado si tienes que enviar toda la lista de la asociación alguna vez. ¿Es eso realmente un requisito? ¿Puedes enviar toda la lista una vez y luego solo actualizaciones?

Cuestiones relacionadas