Для тех, кто заботится о производительности. Есть несколько других способов перебора исходных элементов стека без больших потерь в производительности:
public T[] Stack<T>.ToArray();
public void Stack<T>.CopyTo(T[] array, int arrayIndex);
Я написал грубую программу (ссылка будет указана в конце поста) для измерения производительности и добавил два теста для уже предложенных реализаций (см. Clone1 и Clone2 ) и два теста для ToArray и CopyTo подходов (см. Clone3 и Clone4 , оба они используют более эффективный Array .Reverse метод).
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);
}
}
Результаты:
- Клон1: 318,3766 мс
- Clone2: 269,2407 мс
- Clone3: 50,6025 мс
- Клон4: 37,5233 мс - победитель
Как мы видим, подход с использованием CopyTo метода в 8 раз быстрее и в то же время реализация довольно проста и прямолинейна. Более того, я провел быстрое исследование максимального значения размера стека: тесты Clone3 и Clone4 работали для больших размеров стека до того, как OutOfMemoryException произойдет:
- Clone1: 67108765 элементов
- Clone2: 67108765 элементов
- Clone3: 134218140 элементов
- Clone4: 134218140 элементов
Приведенные выше результаты для Clone1 и Clone2 меньше из-за дополнительных коллекций, которые были явно / неявно определены и, следовательно, влияли на потребление памяти. Таким образом, подходы Clone3 и Clone4 позволяют клонировать экземпляр стека быстрее и с меньшими выделениями памяти. С помощью Reflection вы можете добиться еще лучших результатов, но это уже другая история :)
Полный список программ можно найти здесь .