Perché java non usa un ordinamento radix sui primitivi?


12

java.util.Arrays.sort(/* int[], char[], short[], byte[], boolean[] */) è implementato come un 'quicksort sintonizzato' piuttosto che un ordinamento radix.

Ho fatto un confronto di velocità qualche tempo fa e con qualcosa come n> 10000, l'ordinamento radix era sempre più veloce. perché?

Risposte:


17

Vorrei ipotizzare che:

  • Array.sort è implementato come quicksort, perché quicksort può ordinare qualsiasi cosa in tempo decente, dato un comparatore.
  • L'ordinamento di un elenco di 10000 voci non è così comune. L'accesso a una struttura di dati di 10000 o più elementi è piuttosto comune. Se è necessario mantenere l'ordine, un albero di ricerca bilanciato è spesso un modo migliore di procedere rispetto all'ordinamento dell'intero array ogni volta che è necessario l'elemento più piccolo.
  • L'ordinamento delle primitive non è così comune, nonostante ciò che l'università può insegnare.

Il punto è che non è un caso d'uso così comune che l'ottimizzazione deve trovarsi nella libreria standard. Se hai scritto un'applicazione, che presenta problemi di prestazioni, in cui si determina attraverso la profilazione che l'ordinamento di un array di oltre 10000 ints è effettivamente il collo di bottiglia, è possibile anche scrivere l'ordinamento a mano o riconsiderare la scelta della struttura dei dati nella prima posto.


Non sono sicuro al 100%, ma penso che TimSort sia usato in alcuni casi ora.
Martijn Verburg,

1
Ma non esiste qualcosa come Array.sort, ci sono più Array.sort e la domanda era su questo specializzata per quelli di tipo numerico.
Danubian Sailor,

6

Back2dos ha detto tutto, cercherò solo di chiarire ulteriormente il punto che ritengo più importante:

L'ordinamento Radix può ordinare solo i valori primitivi effettivi contenuti nell'array, in base ai loro modelli di cifre binarie. Negli scenari di ingegneria del software reali, questo caso non si incontra quasi mai . Ciò che tendiamo a fare molto più spesso sono le matrici di ordinamenti di strutture di dati più complesse (non primitive) e alcune volte ordiniamo le matrici di indici ad altre entità.

Ora, una matrice di indici con altre entità è in realtà una matrice di primitive, ma l'ordinamento è fornito dall'interfaccia di confronto (e / o delegato in C #) che confronta non gli indici, ma le entità indicizzate dagli indici. Pertanto, l'ordinamento non ha assolutamente alcuna relazione con l'ordine dei valori delle primitive, e quindi l'ordinamento radix è assolutamente inutile per questo scenario.

Un esempio:

Abbiamo una serie di stringhe: [0] = "Mike", [1] = "Albert", [2] = "Zoro". Quindi dichiariamo una matrice di indici a quelle stringhe: [0] = 0, [1] = 1, [2] = 2. Quindi, ordiniamo l'array di indici, passandogli un comparatore che confronta non gli indici stessi, ma le stringhe effettive a cui fanno riferimento questi indici. Dopo l'ordinamento, l'array di indici risultante sarà simile al seguente: [0] = 1, [1] = 0, [2] = 2. Come puoi vedere, questo ordinamento non ha nulla a che fare con i modelli binari dei valori contenuti nell'array, e tuttavia attraversando questo array di indici e recuperando ogni stringa corrispondente, visitiamo le stringhe in ordine ordinato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.