Prestazioni: looping dei dati sul server o acquisizione dei dati in loop sui client tramite connessione socket

1

Ho un'applicazione web a cui gli utenti di app mobili sono collegati usando websocket. Il server ha dati A che possono essere modificati nel tempo. E i client (app per dispositivi mobili) hanno dati B che possono anche essere modificati nel tempo.

Quando l'utente emette un messaggio (una richiesta per ottenere dati D) sul server usando websocket, devo applicare dei cicli quando eseguo i dati utente B per generare dati C e poi dati D. In questo caso, ci sono 2 opzioni Ho trovato:

( dettaglio: A causa della generazione di dati D ha alcune operazioni di database, i clienti non possono generarli nell'app mobile )

1 °: posso applicare cicli annidati ai dati del server A e dati utente B sul server quando l'utente emette un messaggio (richiesta) in ogni momento. L'operazione ha due cicli annidati e la complessità temporale è O (A * B). Dopo il ciclo avrei dati C per generare dati D.

Pseudo codice:

function generateC () {
    var C = []
    for (let i = 0; i < A.length; i++) {
        for (let j = 0; j < B.length; j++) {
            if (A[i] == B[j]) {
                C.push(A[i])
            }
        }
    }
    generateD(C)
}

2nd: Posso inviare i dati del server A ai client dopo aver compresso i dati. Quindi i client eseguono il ciclo per applicare i dati B ai dati A per generare i dati C. In questo caso, quando si considera la complessità del tempo di caricamento del server è O (N) N è la lunghezza dei caratteri, suppongo.

Pseudo codice:

var compressedA = gzip.compress(A)
socket.to("userX").emit("C", compressedA)
socket.on("C", function (C) {
    generateD(C)
})

Anche il secondo metodo rende il traffico di rete sulla mia larghezza di banda. Immagino che le operazioni di rete siano più costose delle operazioni della CPU.

Quindi vale la pena farlo se il server ha 350.000 utenti attivi?

    
posta efkan 05.05.2017 - 10:32
fonte

1 risposta

0

Stai calcolando un'intersezione impostata. Se vuoi farlo in tempo lineare molto rapidamente e non in tempo quadratico, allora questa è una soluzione estremamente veloce (supererà anche le soluzioni di struttura dati più veloci usando, per esempio, tabelle hash) se puoi permetterti il campo extra booleano (o campo bit se hai un po 'di riserva a portata di mano):

var C = [];

// Mark each element in A.
for (let i = 0; i < A.length; i++) {
    A[i].traversed = true;
}

// Look for elements in B that were marked above.
for (let i = 0; i < B.length; i++) {
    // If B[i] was marked by the above loop (meaning element 
    // was found in both A and B), add it to C.
    if (B[i].traversed) {
        C.push(B[i]);
        B[i].traversed = false;
    }
}

// C now contains the set intersection.

Raccomando di farlo in questo modo sul server per un antipasto invece di cercare di far sì che i client lo calcolino per te. Dubito che diventerà un collo di bottiglia se lo fai in questo modo in tempo lineare e c'è ancora spazio per ulteriori micro-ottimizzazioni altrimenti.

    
risposta data 01.12.2017 - 02:31
fonte