Concerning 1:
Stack<T>‘s and List<T>‘s performance being similar isn’t surprising. I’d expect both of them to use arrays with a doubling strategy. This leads to amortized constant-time additions.
You can use List<T> everywhere you can use Stack<T>, but it leads to less expressive code.
Concerning 2:
I think I know why
List<T>doesn’t handle the front so well… becauseList<T>needs to move the whole list back and fro when doing that.
That’s correct. Inserting/removing elements at the beginning is expensive because it moves all elements. Getting or replacing elements at the beginning on the other hand is cheap.
Concerning 3:
Your slow LinkedList<T>.RemoveLast value is a mistake in your benchmarking code.
Removing or getting the last item of a doubly linked list is cheap. In the case of LinkedList<T> that means that RemoveLast and Last are cheap.
But you weren’t using the Last property, but LINQ’s extension method Last(). On collections that don’t implement IList<T> it iterates the whole list, giving it O(n) runtime.