It contains an optimisation for anything that implements IList<T>
in which case it just looks up the item at length -1.
Keep in mind that the vast majority of stuff you will send in will implement IList<T>
List<int>
int[]
and so on ... all implement IList<T>
For those who can not look at the code to confirm, you can confirm it using observation:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace ConsoleApplication4 {
class Program {
static void Profile(string description, int iterations, Action func) {
// clean up
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
// warm up
func();
var watch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++) {
func();
}
watch.Stop();
Console.Write(description);
Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}
static void Main(string[] args) {
int[] nums = Enumerable.Range(1, 1000000).ToArray();
int a;
Profile("Raw performance", 100000, () => { a = nums[nums.Length - 1]; });
Profile("With Last", 100000, () => { a = nums.Last(); });
Console.ReadKey();
}
}
}
Output:
Raw performance Time Elapsed 1 ms
With Last Time Elapsed 31 ms
So it's only 30 times slower and maintains that performance profile with whatever length list you have, which is nothing in the big scheme of things.