Il modo più veloce per ordinare una matrice in ordine decrescente

Perché è il seguente codice

Array.Sort(values); Array.Reverse(values); 

molto più veloce nell’ordinare una matrice in ordine decrescente rispetto a

 Array.Sort(values, (a,b)=>(-a.CompareTo(b))); 

Il codice è stato eseguito in modalità di rilascio all’esterno del debugger.

Qual è il modo più efficiente per produrre un ordinamento discendente per gli array, preferibilmente in un unico rivestimento?

Questa è una grande domanda. Scommetto che il tuo array di valori è una matrice di tipo primitivo!

È davvero il tipo che è dominante qui, perché la complessità di Reverse è O (n), mentre l’ordinamento è O (n logn).

Il fatto è che quando si ordinano i tipi primitivi, .NET chiama in realtà una funzione nativa, che è estremamente veloce – molto più veloce che usando un Confronto o un Comparatore.

La funzione è chiamata TrySZSort :

 [ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)] [SecurityCritical] [MethodImpl(MethodImplOptions.InternalCall)] private static bool TrySZSort(Array keys, Array items, int left, int right); 

ed ecco come viene chiamato nella class Array:

 [ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)] [SecuritySafeCritical] public static void Sort(T[] array, int index, int length, IComparer comparer) { if (array == null) throw new ArgumentNullException("array"); else if (index < 0 || length < 0) throw new ArgumentOutOfRangeException(length < 0 ? "length" : "index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); else if (array.Length - index < length) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); else if (length > 1 && (comparer != null && comparer != Comparer.Default || !Array.TrySZSort((Array) array, (Array) null, index, index + length - 1))) ArraySortHelper.Default.Sort(array, index, length, comparer); } 

Come sottolinea il collegamento

Il metodo Sort qui finisce sempre in un metodo TrySZSort o QuickSort interno quando non genera un’eccezione. Il metodo interno TrySZSort è ottimizzato per gli array monodesmensionali, noti anche come array “Zero” o vettori

Poiché il metodo TrySZSort utilizzato nelle librerie della class base è implementato nel codice nativo, è stato fortemente ottimizzato. Pertanto, questo metodo è probabilmente più veloce di qualsiasi soluzione scritta nel linguaggio C #

I delegati.

La chiamata al delegato è molto più lenta della chiamata predefinita a IComparable.CompareTo

Aggiornare:

Se si desidera la stessa velocità (o chiusa), implementare l’interfaccia IComparer e passarla al metodo di ordinamento.

http://msdn.microsoft.com/en-us/library/bzw8611x

Perché nella tua seconda versione deve invocare la tua funzione (anonima) ogni volta che esegue un confronto e quindi chiamare .CompareTo al suo interno, in modo da avere due riferimenti indiretti, mentre altrimenti può utilizzare confronti incorporati (per i tipi primitivi).

Fondamentalmente si paga per overhead chiamata di funzione che scommetto sono eliminati per i tipi primitivi nativi quando si eseguono questi tipi di operazioni. Anche se tecnicamente ansible (credo), dubito che il Jitter sia in grado di integrarli completamente nel tuo secondo caso.