Per coloro che si prendono cura di prestazioni ..Ci sono un paio di altri modi per scorrere i membri dello stack originali, senza grandi perdite nella performance:
public T[] Stack<T>.ToArray();
public void Stack<T>.CopyTo(T[] array, int arrayIndex);
ho scritto un programma di massima (il link sarà fornito alla fine del post) per misurare le prestazioni e aggiunto due test per le implementazioni già suggerite (vedi replica1 e Clone2), e due test per ToArray e CopyTo approcci (vedi Clone3 e Clone4, ciascuno di essi un uso più efficiente Array.Reverse metodo).
public static class StackExtensions
{
public static Stack<T> Clone1<T>(this Stack<T> original)
{
return new Stack<T>(new Stack<T>(original));
}
public static Stack<T> Clone2<T>(this Stack<T> original)
{
return new Stack<T>(original.Reverse());
}
public static Stack<T> Clone3<T>(this Stack<T> original)
{
var arr = original.ToArray();
Array.Reverse(arr);
return new Stack<T>(arr);
}
public static Stack<T> Clone4<T>(this Stack<T> original)
{
var arr = new T[original.Count];
original.CopyTo(arr, 0);
Array.Reverse(arr);
return new Stack<T>(arr);
}
}
I risultati sono:
- replica1: 318,3766 ms
- Clone2: 269,2407 ms
- Clone3: 50,6025 ms
- Clone4: 37,5233 ms - the winner
Come noi può vedere, l'approccio usando il metodo CopyTo è 8 volte più veloce e allo stesso tempo l'implementazione è piuttosto semplice e diretta. Inoltre, ho fatto una rapida ricerca su un valore massimo di stack: Clone3 e Clone4 prove lavorato per stack grandi prima OutOfMemoryException verifica:
- replica1: 67108765 elementi
- Clone2: 67108765 elementi
- Clone3: 134218140 elementi
- Clone4: 134218140 elements
I risultati di cui sopra per replica1 e Clone2 sono più piccole a causa di altre raccolte che erano esplicitamente/implicitamente definiti e pertanto influenzata consumo di memoria. Pertanto, Clone3 e Gli approcci Clone4 consentono di clonare un'istanza di stack più veloce e con meno allocazioni di memoria. Puoi ottenere risultati ancora migliori usando Reflection, ma è una storia diversa :)
L'elenco completo del programma può essere trovato here.
tristemente, stranamente, che non conserva l'ordine :((Suppongo che la doppia inizializzazione di uno stack sia errata o sia un trucco?) – SpaceBear
@Angrius: Conserva l'ordine. La doppia istanziazione è un trucco che causa l'ordine da conservare – jason
@Angrius: la "doppia inizializzazione" è necessaria perché ognuno inverte l'ordine.Se lo si inverte due volte si ottiene l'ordine originale – Gabe