2012-03-15 11 views
6

Ho un'app Web che utilizza Guids come PK nel DB per un oggetto Employee e un oggetto Association.Trasferimento di molti oggetti con ID guida al client

Una pagina della mia app restituisce una grande quantità di dati che mostrano tutte le associazioni di cui possono far parte tutti i Dipendenti.

Così adesso, io mando al cliente essenzialmente un gruppo di oggetti che assomigliano:

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

Si scopre che molti dipendenti appartengono a molte associazioni, così io mando giù lo stesso GUID per quei dipendenti più e più volte in questi diversi oggetti. Ad esempio, è possibile che in alcuni casi invii 30.000 guids totali a tutte le associazioni, di cui ci sono solo 500 dipendenti unici.

mi chiedo se vale la pena me la costruzione di una sorta di indice di ricerca che ho anche inviare al client come

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

e sostituendo tutti i GUID negli oggetti mando giù con quei interi,

o se semplicemente gzippare la risposta lo comprimerà abbastanza da non valerne la pena?

Nota: si prega di non farsi prendere nei dettagli di se dovrei mandare giù 30.000 pezzi di dati o meno - questa non è la mia scelta e non c'è nulla che io possa fare al riguardo (e anche io posso cambiare GUID in int e long nel DB).

+0

Perché non usi semplicemente il metodo Linq Distinct()? O utilizzare DISTINCT nella query dbase? –

+0

Perché non inviare l'elenco di * associazione * per * impiegati * invece? – ydroneaud

+0

Per ulteriori motivi relativi alla larghezza di banda della risposta, vorrei separare le risorse nidificate per questo caso, come suggerito. Potresti usare richieste ajax separate per loro, o pigri-caricali su richiesta. – aceofspades

risposta

0

Quindi quello che stai cercando di ottenere è la compressione del dizionario, giusto? http://en.wikibooks.org/wiki/Data_Compression/Dictionary_compression Quello che otterrete invece di Guids che sono lunghi 16 byte è int che è lungo 4 byte. E otterrai un dizionario pieno di coppie di valori chiave che assoceranno ciascun guid ad un valore int, giusto? Ridurrà il tempo di trasferimento quando ci sono molti oggetti con lo stesso ID usato. Ma passerà il tempo della CPU prima del trasferimento per comprimere e dopo il trasferimento per decomprimere. Quindi qual è la quantità di dati che trasferisci? È mb/gb/tb? E c'è qualche buona ragione per comprimerlo prima di inviarlo?

+0

I piccoli numeri interi ** serializzati come JSON ** occupano meno posto della metà del GUID e fungono meno di GUID. Confronta '" {7EDBB957-5255-4b83-A4C4-0DF664905735} "' o '" 7EDBB95752554b83A4C40DF664905735 "' con '499' (34 o 3 caratteri). – Oleg

6

vostro scritto alla fine della tua domanda seguente

Nota: si prega di non farsi prendere nei dettagli di se dovrei essere invio giù 30.000 pezzi di dati o no - questo è non è la mia scelta e non c'è nulla che io possa fare al riguardo (e non posso nemmeno cambiare Guidi in inte o long nel DB).

Penso che sia il tuo problema principale. Se non risolvi il problema principale, ad esempio sarai in grado di ridurre la dimensione dei dati trasferiti a 10 volte, ma non risolvi il problema principale. Pensiamo alla domanda: Perché così tanti dati devono essere inviati al client (al browser web)?

I dati sul lato client sono necessari per visualizzare le informazioni all'utente. Il monitor non è così grande da mostrare 30.000 totali su una pagina. Nessun utente è in grado di cogliere così tante informazioni. Quindi sono sicuro che mostri solo una piccola parte delle informazioni. Nel caso dovessi inviare solo la piccola parte di informazioni che visualizzi.

Non si descrive come verranno utilizzati i guids sul lato client. Se hai bisogno delle informazioni durante la modifica delle righe, ad esempio. È possibile trasferire i dati solo quando l'utente inizia a modificare. Nel caso in cui sia necessario trasferire i dati solo per un'associazione.

Se è necessario visualizzare i guids direttamente, non è possibile visualizzare tutte le informazioni contemporaneamente. Quindi puoi inviare le informazioni per una sola pagina. Se l'utente inizia a scorrere o avvia il pulsante "pagina successiva", è possibile inviare la successiva porzione di dati. Nel modo in cui puoi davvero ridurre drasticamente la dimensione dei dati trasferiti.

Se si ha alcuna possibilità di ridisegnare la parte di applicazione è possibile implementare la tua proposta originale: sostituendo di GUID "{7EDBB957-5255-4b83-A4C4-0DF664905735}" o "7EDBB95752554b83A4C40DF664905735" al numero come 123 si riducono le dimensioni del GUID da 34 caratteri a 3. Se si vuole inviare inoltre array di elementi "guid mappatura" come

123:"7EDBB95752554b83A4C40DF664905735", 

è possibile ridurre le dimensioni originali dei dati 30000 * 34 = 1020000 (1 MB) a 300 * 39 + 30000 * 3 = 11700 + 90000 = 101700 (100 KB). In questo modo è possibile ridurre la dimensione dei dati in 10 volte. L'utilizzo della compressione dei dati dinamici sul server Web può ridurre ulteriormente la dimensione dei dati.

In qualsiasi modo è necessario esaminare perché la pagina è così lentamente. Se il programma funziona in LAN, il trasferimento di anche 1 MB di dati può essere abbastanza veloce. Probabilmente la pagina è lentamente durante il posizionamento dei dati sulla pagina web. Intendo il seguente. Se si modifica un elemento nella pagina, la posizione di tutti gli elementi esistenti devono essere ricalcolati. Se prima dovessi lavorare con oggetti DOM disconnessi e poi inserire l'intera porzione di dati nella pagina, puoi migliorare notevolmente le prestazioni. Non hai inserito nella domanda la tecnologia che usi nella tua applicazione web, quindi non includo esempi. Ad esempio, se usi jQuery, potrei dare qualche esempio che chiarisca meglio cosa intendo.

+0

A volte allo sviluppatore vengono forniti requisiti che non possono cambiare, nonostante la logica di un approccio alternativo. Penso che Davis sia abbastanza chiaro nell'indicare che è la situazione qui. – Random

+0

@Random: se si può cambiare il formato della risposta del server come sostituendolo con l'indice nell'array '[Guid1, Guid2, ...]' allora un * do * può cambiare il protocollo tra la comunicazione tra il server e il cliente. Sappiamo troppo poche informazioni sul problema. Volevo dire che il trasferimento di 30.000 guids totali per una pagina è definitivamente * eccessivo quanto necessario per visualizzare le informazioni esistenti nella pagina *. Suppongo che se si analizza il problema più sotto l'aspetto si può ridurre la dimensione dei dati trasferiti in molte volte. – Oleg

+0

Non necessariamente non sono d'accordo. E l'informazione nella tua risposta è utile. Sto solo affermando che dal momento che anche Davis sembra comprenderlo, limita l'applicabilità della risposta al suo problema specifico. – Random

2

L'indice di ricerca proposto non è altro che uno schema di compressione "personalizzato". Come dichiarato da amdmax, questo aumenterà le prestazioni se si hanno molti GUID uguali, ma quindi gzip.

IMHO, lo sforzo extra di scrivere la codifica personalizzata non varrà la pena.

Oleg afferma correttamente che potrebbe valere la pena di recuperare i dati solo quando l'utente ne ha bisogno. Ma questo ovviamente dipende dalle tue esigenze specifiche.

1

se semplicemente gzipping la risposta lo comprimerà abbastanza da non valerne la pena?
La risposta è: Sì, sarà.

La compressione dei dati rimuoverà le parti ridondanti nel miglior modo possibile (in base all'algoritmo) fino alla decompressione.

Per essere sicuri, basta inviare/generare i dati non compressi e compressi e confrontare i risultati. È possibile contare i GUID duplicati per calcolare quanto grande sarebbe il blocco di dati con il metodo di compressione del dizionario. Ma credo che gzip sarà migliore perché può anche comprimere gli elementi sintattici come parentesi graffe, due punti, ecc. All'interno dell'oggetto dati.

+0

Dopo aver eseguito alcuni test, risulta che si tratta di circa il 50% di dati in più per trasferire l'intera cosa gzip'd rispetto alla compressione del dizionario. Purtroppo abbastanza consistente –

0

Non so come dinamico è i vostri dati, ma vorrei

  • su una prima chiamata inviare due directory/dizionari di mappatura brevi IDS a lunghi GUID, uno per le associazioni e per i vostri dipendenti per esempio {1: AssoGUID1, 2: AssoGUID2, ...} e {1: EmpGUID1, 2: EmpGUID2, ...}. Queste directory possono anche contenere informazioni aggiuntive sulle istanze di Associazioni e Dipendenti; Sospetto che tu non mostri semplicemente GUID

  • sulle chiamate successive, basta inviare l'indice di Dipendenti per associazione {1: [2,4,5], 3: [2,4], ...}, la chiave essendo l'id breve di associazione e gli id ​​nel valore dell'array, gli id ​​brevi dei dipendenti. Data la sua descrizione costruire l'indice inverso: Dipendente ad Associazioni può dare una migliore dimensioni risultato saggio (ma maggiori lavorazioni)

Poi sua tutti giù per array associativi manipolazioni che è semplice in JS.

Anche in questo caso, se i dati sono (molto) dinamici sul lato server, le due directory saranno presto obsolete e il mantenimento della sincronizzazione potrebbe costare molto.

0

Vorrei iniziare rispondendo alle seguenti domande:

Quali sono i requisiti di prestazione? Ci sono dei requisiti di dimensioni? Requisiti di velocità? Qual è la prestazione minima che è veramente necessaria?

Quali sono le metriche di rendimento correnti? Quanto sei lontano dai requisiti?

Hai caratterizzato i dati come se fossero per lo più ripetizioni. È normale? Se no, che cos'è?

Le 2 opzioni sopra elencate sono ragionevoli e banali da implementare. Prova a creare una tabella di ricerca e scopri quali sono le prestazioni ottenute con le query effettive. Prova a comprimere i risultati (con look-up e senza), e guarda che guadagni ottieni.

Nella mia esperienza, se non sei TROPPO lontano dall'obiettivo, i requisiti di prestazione sono spesso tentativi ed errori.

Se queste opzioni non ti avvicinano ai requisiti, farei un passo indietro e vedere se i requisiti sono ragionevoli nel tempo necessario per risolvere il problema.

Quello che fai dopo dipende da quali obiettivi di rendimento mancano. Se è di dimensioni, stai iniziando a essere limitato se ti viene richiesto di inviare l'intera lista di associazioni in qualsiasi momento. È davvero un requisito? Puoi inviare l'intero elenco una volta e poi solo gli aggiornamenti?

Problemi correlati