Più ordini in una singola lista

1

Ho un problema con un sistema di classificazione che sto usando.

Scenario:

Un gioco online con circa 10k giocatori calcola una classifica dei punti in tempo reale quando si verifica un determinato evento. Gli eventi non si verificano spesso, circa 1 volta al minuto. Questa classifica viene mantenuta nella cache per calcoli, ordinamenti e accessi rapidi.

Ora i giocatori possono formare gruppi e giocare uno contro l'altro, ma il sistema di punteggio è lo stesso, solo la classifica è basata per i giocatori di quel gruppo.

All'inizio ho creato per ogni gruppo una classifica separata, con gli stessi punteggi della classifica completa, ma con posizioni diverse nella classifica.

Questo è banale perché ci sono oltre 1.000 gruppi e ogni volta che si verifica un evento, tutti i gruppi dovrebbero essere aggiornati.

Quindi quello che ho fatto ora è quando la classifica di gruppo è richiesta, prendere solo i giocatori che si trovano in quel gruppo dalla classifica completa e mostrarli. Le posizioni dovrebbero essere ricontestualizzate.

Il riconteggio è dove si trova il problema. Poiché la sotto-lista è per riferimento dalla graduatoria completa non posso modificare la posizione del giocatore nella sottocategoria senza aggiornarla nella classifica completa, perché è solo un riferimento.

Ho trovato due soluzioni:

  • Crea una copia dal record ogni volta che viene richiesta e fai un po 'di output nella cache (non molto desiderabile perché le classifiche sono live)
  • Crea una copia e memorizzala in una cache che viene ripristinata quando si verifica un evento.
  • Crea una sottocategoria con solo le posizioni che vengono aggiornate quando si verifica un evento.

E l'ultima soluzione: fare il conteggio delle posizioni nell'output invece nel lato business. Questa sarebbe la soluzione migliore, il solo problema è che su alcune pagine appare questo testo: "Sei sulla posizione # nella classifica" dove # è la tua posizione in classifica. Questo numero sarebbe noioso da ottenere allora.

Qualcuno ha qualche suggerimento su questo problema?

    
posta YesMan85 20.05.2013 - 22:29
fonte

2 risposte

2

Potrebbero esserci delle considerazioni sulle prestazioni minori, ma questo suona come il tipo di cosa per cui LINQ è molto utile. L'idea di base è questa:

var enormousList = new List<record>();

//var enormousList = ... (over 5 million records)
var subList = enormousList.Where(onerecord => onerecord.clanName == "RAGIN CAJUN");

// At this point in the program, NO filtration has occurred just yet and little processing
// power has been used.

// This enumerates the list once for the "ragin cajun" filter, so this may take a while.
var sublistCount = subList.Count(); //take note that Count is a function here, not a property. 
var pageSize = 50;
var hudDisplayPage = enormousList.Take(pageSize).Select((record, idx) =>
{
    return new HudPage(idx, record.clanName, record.playerName);
});
// for those who couldn't keep track; hudDisplayPage is now an IEnumerable (which you can use for-each on) containing
// 50 records of the list fitting the description. These are dynamic constructs; even now, hudDisplayPage hasn't
// yet been evaluated. If you want to cache one of these values so you're not doing the processing again later...
var saved = hudDisplayPage.ToArray();

Questo tipo di sistema dovrebbe rendere relativamente semplice la rimozione dei dati e precache quali sono probabilmente necessarie più volte. Inoltre, prendi nota di questo suggerimento pratico (ma SOLO per le query che finiscono per essere un successo in termini di prestazioni)

var saved = hudDisplayPage.AsParallel().ToArray();

Quella linea dovrebbe essenzialmente multithread il processo di filtraggio, in modo che tutti i core del processore siano su di esso.

Non posso dire di conoscere abbastanza il tuo problema per scrivere la sua soluzione nel codice; ma sembra che il tuo problema riguardi principalmente l'elaborazione dell'elenco, contro una singola lista che non vuoi modificare o copiare. Spero di non aver frainteso il tuo problema!

    
risposta data 21.05.2013 - 02:29
fonte
2

Come dici tu stesso, la soluzione migliore è fare il conteggio nell'output, invece di memorizzarlo nei vari elenchi. In questo modo non devi memorizzare (e ricalcolare) i numeri di classifica su ciascun evento per ogni (sotto) elenco, ma li calcoli solo quando necessario.

Per il testo "Sei nella posizione # nel testo della classifica", potresti avere un metodo nella classe che rappresenta la classifica, in questo modo: RankingList::getRankingOf(Player) . Solo se queste informazioni sono costose da ottenere e hai bisogno solo del ranking dall'elenco generale, potresti prendere in considerazione la memorizzazione nella cache dei numeri di classifica correnti nell'elenco generale (come strategia di ottimizzazione).

    
risposta data 21.05.2013 - 16:50
fonte

Leggi altre domande sui tag