2010-09-15 22 views
5

Trascorro del tempo implementando un algoritmo di quicksort in C#. Dopo aver terminato, ho confrontato la velocità della mia implementazione e il metodo Array.Sort di C#.Implementazione dell'algoritmo di ordinamento sicuro più veloce

Confronto solo la velocità su array int casuali.

Ecco la mia realizzazione:

static void QuickSort(int[] data, int left, int right) 
{ 
    int i = left - 1, 
     j = right; 

    while (true) 
    { 
     int d = data[left]; 
     do i++; while (data[i] < d); 
     do j--; while (data[j] > d); 

     if (i < j) 
     { 
      int tmp = data[i]; 
      data[i] = data[j]; 
      data[j] = tmp; 
     } 
     else 
     { 
      if (left < j) QuickSort(data, left, j); 
      if (++j < right) QuickSort(data, j, right); 
      return; 
     } 
    } 
} 

Performance (durante l'ordinamento un int casuale [] con la lunghezza di 100 milioni):
      - il mio algoritmo: 14.21 secondi
      - Net Array <int.>. Numero: 14,84 secondi

Qualcuno sa come implementare il mio a algoritmo ancora più veloce?
Oppure qualcuno può fornire un'implementazione più veloce (non è necessario essere un quicksort!) Che la mia corsa più veloce?

Nota:
      - si prega di non algoritmi che usano più core/processori per migliorare perrformance
      - unica sorgente C# valido codice

mi metterà alla prova le prestazioni degli algoritmi forniti all'interno di un pochi minuti se sono online.

MODIFICA:
Pensi che l'utilizzo di una rete di ordinamento ideale per le parti che contengono meno di 8 valori migliorerebbe le prestazioni?

+4

prova a ripetere i tempi quando un array è già in ordine ... Quindi con un array che ha solo due degli articoli nell'ordine sbagliato .. –

+2

Un guadagno di prestazioni del 4,3% - Lo stai facendo per ragioni accademiche? – flq

+2

Ian è corretto sulla matrice già ordinata. La scelta di un elemento pivot avrà prestazioni orribili nel caso peggiore. Detto questo, accelerare Quicksort è abbastanza semplice. Selezionare un pivot migliore utilizzando qualcosa come il metodo MedianOfThree e utilizzare un algoritmo di ordinamento più appropriato per le partizioni piccole. Presumo che tu stia facendo questo per la ricerca personale perché usare il metodo di ordinamento della libreria di sistema è quasi sempre la risposta giusta. – Blastfurnace

risposta

7

Qualcuno sa come implementare l'algoritmo ancora più veloce?

Sono stato in grado di ridurre del 10% il tempo di esecuzione convertendo il codice per utilizzare i puntatori.

public unsafe static void UnsafeQuickSort(int[] data) 
    { 
     fixed (int* pdata = data) 
     { 
      UnsafeQuickSortRecursive(pdata, 0, data.Length - 1); 
     } 
    } 

    private unsafe static void UnsafeQuickSortRecursive(int* data, int left, int right) 
    { 
     int i = left - 1; 
     int j = right; 

     while (true) 
     { 
      int d = data[left]; 
      do i++; while (data[i] < d); 
      do j--; while (data[j] > d); 

      if (i < j) 
      { 
       int tmp = data[i]; 
       data[i] = data[j]; 
       data[j] = tmp; 
      } 
      else 
      { 
       if (left < j) UnsafeQuickSortRecursive(data, left, j); 
       if (++j < right) UnsafeQuickSortRecursive(data, j, right); 
       return; 
      } 
     } 
    } 
+0

c'è un piccolo bug, ma davvero bello l'aggiornamento (+1), 1.1 secondi più veloce sul mio hardware! – raisyn

+8

Questo non coincide con il requisito "sicuro" nel titolo? – Gabe

+0

È un po 'difficile da dire ... anche questo è abbastanza semplice ... Volevo solo essere sicuro di non ottenere codici C/C++ ottimizzati. – raisyn

8

L'ordinamento di inserimento binario quasi sempre vince per tirature brevi (~ 10 articoli). Spesso è meglio di una rete di ordinamento ideale a causa della struttura di diramazione semplificata.

Dual pivot quicksort è più veloce di quicksort. Il documento collegato contiene un'implementazione Java che potresti presumibilmente adattare.

Se si stanno solo ordinando numeri interi, un radix sort sarà probabilmente ancora più veloce su array lunghi.

+1

Questo link non funziona più. –

0

Questo primo (e probabilmente il secondo) algoritmo di ordinamento rapido si interrompe quando si ordinano gli array con elementi duplicati. Ho usato uno this, che funziona bene.

Problemi correlati