2009-10-15 22 views
22

Mi chiedo circa i parametri per la costruzione di un ConcurrentHashMap:Parametri del costruttore ConcurrentHashMap?

  • initialCapacity è 16 per default (compreso).
  • loadFactor è 0,75 per impostazione predefinita.
  • concurrencyLevel è 16 per impostazione predefinita.

Le mie domande sono:

  • Quali criteri dovrebbero essere utilizzati per regolare loadFactor alto o in basso?
  • Come si stabilisce il numero di thread di aggiornamento simultaneo?
  • Quali criteri devono essere utilizzati per regolare concurrencyLevel in alto o in basso?

Inoltre:

  • Quali sono le caratteristiche di una buona implementazione hashcode ? (Se una domanda SO si rivolge a questo, basta collegarlo.)

Grazie!

+0

Grazie Dave, molto meglio farò la mia coda da te –

risposta

15

La risposta breve: impostare "capacità iniziale" su un numero approssimativo di mapping che si prevede di inserire nella mappa e lasciare gli altri parametri ai valori predefiniti.

Risposta lunga:

  • fattore di carico è il rapporto tra il numero di "secchi" nella mappa e il numero degli elementi previsti;

  • 0,75 è di solito un compromise-- ragionevole come ricordo, significa che con una buona funzione di hash , in media ci aspettiamo circa 1.6 reindirizzamenti per trovare un elemento nella mappa (o intorno a quella figura);

    • cambiando il fattore di carico cambia il compromesso tra più reindirizza a trovare un elemento, ma meno sprecato space-- messo 0.75 è davvero di solito un buon rapporto;

    • in linea di principio, impostare ConcurrencyLevel al il numero di thread simultanei si aspettano di avere la modifica della mappa, anche se sopravvalutare questo non sembrano avere un effetto negativo altra che sprecare memoria (ho scritto un po ' su ConcurrentHashMap performance qualche tempo fa nel caso in cui siete interessati )

Informalmente, il vostro hash la funzione dovrebbe essenzialmente mirare ad avere il maggior numero possibile di "casualità" nei bit. O più rigorosamente, il codice hash per un dato elemento dovrebbe dare ad ogni bit una probabilità del 50% circa di essere impostato. In realtà è più semplice illustrarlo con un esempio: ancora una volta potresti essere interessato a qualcosa che ho scritto su how the String hash function works e associato allo hash function guidelines. Il feedback è benvenuto su qualsiasi di queste cose.

Una cosa ho detto anche ad un certo punto è che non c'è bisogno di essere troppo paranoici in pratica: se la funzione di hash produce una quantità "ragionevole" di casualità in alcune dei bit, allora sarà spesso Essere a posto. Nel peggiore dei casi, incollare pezzi rappresentativi di dati in una stringa e prendere il codice hash della stringa in realtà non funziona così male.

0

loadFactor: controlla quando l'implementazione decide di ridimensionare la tabella hash. Un valore troppo alto perderà spazio; un valore troppo basso si tradurrà in costose operazioni di ridimensionamento.

concurrencyLevel: indica all'implementazione di provare a ottimizzare per il numero specificato di thread di scrittura. Secondo i documenti dell'API, la riduzione fino a un fattore 10 non dovrebbe avere un grande effetto sulle prestazioni.

La concorrenza tra permesso di aggiornamento operazioni è guidato dal opzionale concurrencyLevel costruttore argomento (default 16), che è usato come un suggerimento per collatura. La tabella è internamente partizionata per provare a consentire il numero indicato di aggiornamenti simultanei senza contesa. Poiché il posizionamento nelle tabelle hash è in genere uguale a , la concorrenza effettiva di varia. Idealmente, è necessario scegliere un valore per per in modo che modifichi contemporaneamente la tabella. L'utilizzo di un valore significativamente superiore a rispetto a quello può sprecare spazio e tempo e un valore significativamente inferiore di può portare a contesa del thread . Ma sopravvaluta e sottostima entro un ordine di grandezza di solito non ha molto impatto notevole.

Una buona implementazione di hashcode distribuirà i valori di hash in modo uniforme su qualsiasi intervallo. Se il set di chiavi è noto in anticipo, è possibile definire una funzione di hash "perfetta" che crea un valore hash univoco per ogni chiave.

0

loadFactor è impostato su 0,75 per impostazione predefinita, quali criteri dovrebbero essere utilizzati per regolare questo alto o in basso?

Hai bisogno di un po 'di esperienza nel modo in cui funzionano le mappe di hash prima di poter capire come funziona. La mappa è essenzialmente una serie di secchi. Ogni valore nella mappa viene inserito in un bucket a seconda di quale sia il suo codice hash. Il loadFactor significa che, se i secchi sono pieni oltre il 75%, la mappa dovrebbe essere ridimensionato

concurrencyLevel è impostato su 16 per impostazione predefinita , come facciamo a stabilire il numero di contemporaneamente aggiornare discussioni? Quali criteri dovrebbero essere utilizzati per regolare questo su o giù?

Questo chiede il numero di thread per che ci si aspetta di modificare la mappa contemporaneamente (contemporaneamente)

Per i codici hash, vedere Effective Java

4

Fattore di carico di Joshua Bloch è principalmente legato alla qualità del hash funzione. Più vicino a zero è il fattore di carico, meno è probabile che vi siano collisioni anche se la funzione di hash non è così grande. Il compromesso è che l'impronta della memoria è più grande. In altre parole, HashMap non distribuisce le voci in bucket separati per ogni hashcode separato, le raggruppa per prossimità, quindi più bucket ha, maggiore è la distribuzione, minore è la probabilità che ci siano collisioni.

Quindi la linea di fondo è giocherellare con il fattore di carico per migliorare il tempo di ricerca o ridurre la memoria, in base alle proprie esigenze e agli oggetti che si stanno memorizzando nella mappa.

ConcurrencyLevel dipende davvero dall'applicazione. Se hai solo due o tre thread in esecuzione nell'applicazione, ecco fatto. Se si è un server applicazioni con un numero arbitrario di thread, è necessario capire qual è la capacità di carico e il punto per cui si desidera ottimizzare.

Un'implementazione di hashcode di buona qualità fornisce una distribuzione quanto più ampia possibile dei possibili valori dell'oggetto con il minor numero di collisioni, rispettando il contratto. In altre parole, consente a HashMap (o Set, a seconda dei casi) di distribuire gli oggetti in bucket separati che rendono più veloci le ricerche.

Problemi correlati