Para aquellos que cuidan de rendimiento ..Hay algunas otras formas forma de repetición de los miembros de la pila originales, sin grandes pérdidas en el rendimiento:
public T[] Stack<T>.ToArray();
public void Stack<T>.CopyTo(T[] array, int arrayIndex);
me escribió un programa en bruto (el enlace se proporciona al final del post) para medir el desempeño y añadido dos pruebas para las implementaciones que han sido sugeridas (ver Clone1 y Clone2), y dos pruebas para ToArray y CopyTo enfoques (ver Clone3 y Clone4, tanto de ellos un uso más eficiente Array.Reverse método).
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);
}
}
Los resultados son:
- Clone1: 318,3766 ms
- Clone2: 269,2407 ms
- Clone3: 50,6025 ms
- Clone4: 37,5233 ms - el ganador
Como nosotros puede ver, el enfoque que usa El método CopyTo es 8 veces más rápido y, al mismo tiempo, la implementación es bastante simple y directa. Por otra parte, hice una búsqueda rápida en un valor máximo de tamaño de la pila: Clone3 y Clone4 pruebas trabajaron para grandes tamaños de pila antes de OutOfMemoryException ocurre:
- Clone1: 67108765 elementos
- Clone2: 67108765 elementos
- Clone3: 134218140 elementos
- Clone4: 134218140 elementos
Los resultados anteriores para Clone1 y Clone2 son más pequeños debido a las colecciones adicionales que eran explícitamente/consumo de memoria definido implícitamente y por lo tanto afectada. Por lo tanto, Clone3 y Clone4 enfoques permiten clonar una instancia de pila más rápido y con menos asignaciones de memoria. Puede obtener resultados aún mejores utilizando Reflection, pero es una historia diferente :)
El listado completo del programa se puede encontrar here.
tristemente, curiosamente, eso no conserva el orden :((Supongo que la doble inicialización de una pila es un error tipográfico o es un truco?) – SpaceBear
@Angrius: Conserva el orden. La doble instancia es un truco que causa el orden que debe conservarse – jason
@Angrius: se requiere la "inicialización doble" porque cada uno invierte el orden. Si lo invierte dos veces, obtendrá el orden original. – Gabe