Skip to content
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

Tweak Enumerable.ToArray to reduce some overheads #97458

Merged
merged 4 commits into from
Jan 27, 2024

Conversation

stephentoub
Copy link
Member

Fixes dotnet/perf-autofiling-issues#27364
Fixes #96852

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

BenchmarkSwitcher.FromAssembly(typeof(Tests).Assembly).Run(args);

public class Tests
{
    [Params(1, 10, 1000)]
    public int Length { get; set; }

    [GlobalSetup]
    public void Setup()
    {
        _intsCollection = Enumerable.Range(0, Length).ToArray();
        _objectsCollection = Enumerable.Repeat(new object(), Length).ToArray();
        _intsEnumerable = Iterate(Enumerable.Range(0, Length).ToArray());
        _objectEnumerable = Iterate(Enumerable.Repeat(new object(), Length).ToArray());
    }

    private IEnumerable<int> _intsCollection;
    private IEnumerable<object> _objectsCollection;
    private IEnumerable<int> _intsEnumerable;
    private IEnumerable<object> _objectEnumerable;

    [Benchmark]
    public int[] IntCollection() => _intsCollection.ToArray();

    [Benchmark]
    public object[] ObjectCollection() => _objectsCollection.ToArray();

    [Benchmark]
    public int[] IntEnumerable() => _intsEnumerable.ToArray();

    [Benchmark]
    public object[] ObjectEnumerable() => _objectEnumerable.ToArray();

    private static IEnumerable<T> Iterate<T>(IEnumerable<T> source)
    {
        foreach (var item in source) yield return item;
    }
}
Method Toolchain Length Mean Ratio
IntCollection \main\corerun.exe 1 18.68 ns 1.00
IntCollection \pr\corerun.exe 1 15.73 ns 0.84
ObjectCollection \main\corerun.exe 1 35.72 ns 1.00
ObjectCollection \pr\corerun.exe 1 31.48 ns 0.88
IntEnumerable \main\corerun.exe 1 49.37 ns 1.00
IntEnumerable \pr\corerun.exe 1 48.62 ns 0.98
ObjectEnumerable \main\corerun.exe 1 86.93 ns 1.00
ObjectEnumerable \pr\corerun.exe 1 82.68 ns 0.95
IntCollection \main\corerun.exe 10 21.33 ns 1.00
IntCollection \pr\corerun.exe 10 18.99 ns 0.92
ObjectCollection \main\corerun.exe 10 45.16 ns 1.00
ObjectCollection \pr\corerun.exe 10 42.48 ns 0.94
IntEnumerable \main\corerun.exe 10 130.02 ns 1.00
IntEnumerable \pr\corerun.exe 10 126.27 ns 0.96
ObjectEnumerable \main\corerun.exe 10 261.53 ns 1.00
ObjectEnumerable \pr\corerun.exe 10 248.10 ns 0.95
IntCollection \main\corerun.exe 1000 388.00 ns 1.00
IntCollection \pr\corerun.exe 1000 393.29 ns 1.01
ObjectCollection \main\corerun.exe 1000 839.89 ns 1.00
ObjectCollection \pr\corerun.exe 1000 844.79 ns 1.01
IntEnumerable \main\corerun.exe 1000 5,990.03 ns 1.00
IntEnumerable \pr\corerun.exe 1000 5,456.53 ns 0.91
ObjectEnumerable \main\corerun.exe 1000 11,796.91 ns 1.00
ObjectEnumerable \pr\corerun.exe 1000 11,928.09 ns 1.01

@ghost
Copy link

ghost commented Jan 24, 2024

Tagging subscribers to this area: @dotnet/area-system-linq
See info in area-owners.md if you want to be subscribed.

Issue Details

Fixes dotnet/perf-autofiling-issues#27364
Fixes #96852

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

BenchmarkSwitcher.FromAssembly(typeof(Tests).Assembly).Run(args);

public class Tests
{
    [Params(1, 10, 1000)]
    public int Length { get; set; }

    [GlobalSetup]
    public void Setup()
    {
        _intsCollection = Enumerable.Range(0, Length).ToArray();
        _objectsCollection = Enumerable.Repeat(new object(), Length).ToArray();
        _intsEnumerable = Iterate(Enumerable.Range(0, Length).ToArray());
        _objectEnumerable = Iterate(Enumerable.Repeat(new object(), Length).ToArray());
    }

    private IEnumerable<int> _intsCollection;
    private IEnumerable<object> _objectsCollection;
    private IEnumerable<int> _intsEnumerable;
    private IEnumerable<object> _objectEnumerable;

    [Benchmark]
    public int[] IntCollection() => _intsCollection.ToArray();

    [Benchmark]
    public object[] ObjectCollection() => _objectsCollection.ToArray();

    [Benchmark]
    public int[] IntEnumerable() => _intsEnumerable.ToArray();

    [Benchmark]
    public object[] ObjectEnumerable() => _objectEnumerable.ToArray();

    private static IEnumerable<T> Iterate<T>(IEnumerable<T> source)
    {
        foreach (var item in source) yield return item;
    }
}
Method Toolchain Length Mean Ratio
IntCollection \main\corerun.exe 1 18.68 ns 1.00
IntCollection \pr\corerun.exe 1 15.73 ns 0.84
ObjectCollection \main\corerun.exe 1 35.72 ns 1.00
ObjectCollection \pr\corerun.exe 1 31.48 ns 0.88
IntEnumerable \main\corerun.exe 1 49.37 ns 1.00
IntEnumerable \pr\corerun.exe 1 48.62 ns 0.98
ObjectEnumerable \main\corerun.exe 1 86.93 ns 1.00
ObjectEnumerable \pr\corerun.exe 1 82.68 ns 0.95
IntCollection \main\corerun.exe 10 21.33 ns 1.00
IntCollection \pr\corerun.exe 10 18.99 ns 0.92
ObjectCollection \main\corerun.exe 10 45.16 ns 1.00
ObjectCollection \pr\corerun.exe 10 42.48 ns 0.94
IntEnumerable \main\corerun.exe 10 130.02 ns 1.00
IntEnumerable \pr\corerun.exe 10 126.27 ns 0.96
ObjectEnumerable \main\corerun.exe 10 261.53 ns 1.00
ObjectEnumerable \pr\corerun.exe 10 248.10 ns 0.95
IntCollection \main\corerun.exe 1000 388.00 ns 1.00
IntCollection \pr\corerun.exe 1000 393.29 ns 1.01
ObjectCollection \main\corerun.exe 1000 839.89 ns 1.00
ObjectCollection \pr\corerun.exe 1000 844.79 ns 1.01
IntEnumerable \main\corerun.exe 1000 5,990.03 ns 1.00
IntEnumerable \pr\corerun.exe 1000 5,456.53 ns 0.91
ObjectEnumerable \main\corerun.exe 1000 11,796.91 ns 1.00
ObjectEnumerable \pr\corerun.exe 1000 11,928.09 ns 1.01
Author: stephentoub
Assignees: -
Labels:

area-System.Linq

Milestone: -

@stephentoub stephentoub merged commit 19d5ae1 into dotnet:main Jan 27, 2024
109 of 111 checks passed
@stephentoub stephentoub deleted the tweaktoarray branch January 27, 2024 13:08
@github-actions github-actions bot locked and limited conversation to collaborators Feb 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Perf] Linux/x64: 12 Regressions on 1/11/2024 5:32:36 PM [Perf] Linux/arm64: 3 Regressions in LINQ
2 participants