-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve Enumerable.Skip and Enumerable.Take performance #112401
Improve Enumerable.Skip and Enumerable.Take performance #112401
Conversation
Tagging subscribers to this area: @dotnet/area-system-linq |
What does the performance look like for |
@EgorBot -amd -arm using System.Collections.Immutable;
using BenchmarkDotNet.Attributes;
[MemoryDiagnoser]
public class Benchmark
{
private readonly IList<string> _list = Enumerable.Range(0, 1000)
.Select(i => i.ToString()).ToImmutableArray();
[Benchmark]
public List<string> SkipAndTake() =>
_list.Skip(200).Take(200).ToList();
} |
I think with help of PGO, these casts are cheap (at least, in monomorphic microbenchmarks). Presumably the overhead is more visible on smaller inputs and when the input is diverse (so PGO can't help). |
Perhaps using one benchmark class to run three against three different input types could help here? |
Even with small inputs there was not much degradation in performance
[MemoryDiagnoser]
public class Benchmark
{
[Params(2, 20, 200, 2000)]
public int SkipCount { get; set; }
[Params(5, 50, 500, 5000)]
public int TakeCount { get; set; }
private readonly List<string> _list = Enumerable.Range(0, 10000).Select(i => i.ToString()).ToList();
private readonly ReadOnlyCollection<string> _readOnlyCollection = Enumerable.Range(0, 10000).Select(i => i.ToString()).ToList().AsReadOnly();
[Benchmark]
public List<string> ReadOnlyCollection_SkipAndTake() =>
_readOnlyCollection.Skip(SkipCount).Take(TakeCount).ToList();
[Benchmark]
public List<string> ReadOnlyCollection_SkipAndTake_PR() =>
_readOnlyCollection.Skip_PR(SkipCount).Take_PR(TakeCount).ToList();
[Benchmark]
public List<string> List_SkipAndTake() =>
_list.Skip(SkipCount).Take(TakeCount).ToList();
[Benchmark]
public List<string> List_SkipAndTake_PR() =>
_list.Skip_PR(SkipCount).Take_PR(TakeCount).ToList();
[Benchmark]
public List<string> List_GetRange() =>
_list.GetRange(SkipCount, TakeCount);
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
Summary
CopyTo
is now used inToArray
andToList
afterSkip
andTake
when source isList<T>
orT[]
.Benchmark