I needed a TakeLast<T>(int n) -style LINQ function. I came across this StackOverflow post: https://stackoverflow.com/a/3453282/825011. I liked this answer simply because it was a simple implementation. Then, another colleague of mine pointed out that the Reverse() must be more-costly than Skip(length - n). Which caused me to write a test.
Here are the competing functions.
public static IEnumerable<T> TakeLast<T>( this IEnumerable<T> c, int n ) {
return c.Reverse().Take( n ).Reverse();
}
public static IEnumerable<T> TakeLast2<T>( this IEnumerable<T> c, int n ) {
var count = c.Count();
return c.Skip( count - n );
}
I timed the execution of obtaining the last 10 elements of the enumeration Enumerable.Range( 0, 100000 ). I found that:
TakeLast()is faster ~5x.- Enumerations of
TakeLast()are significantly faster after the first enumeration.
Here's the .NET Fiddle for my code (which was originally ran locally, but is also demonstrated here.): http://dotnetfiddle.net/ru7PZE
Questions
- Why is
TakeLast()faster? - Why are the second and third enumerations of
TakeLast()faster than the first, but all enumerations ofTakeLast2()are about the same?