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?