KEMBAR78
Optimize Enumerable.OfType with custom iterator by stephentoub · Pull Request #99216 · dotnet/runtime · GitHub
Skip to content

Conversation

@stephentoub
Copy link
Member

Method Toolchain Target Mean Ratio Allocated Alloc Ratio
OfTypeForEach \main\corerun.exe Object 112.64 ns 1.00 88 B 1.00
OfTypeForEach \pr\corerun.exe Object 66.18 ns 0.59 80 B 0.91
OfTypeCount \main\corerun.exe Object 119.40 ns 1.00 88 B 1.00
OfTypeCount \pr\corerun.exe Object 101.25 ns 0.85 80 B 0.91
OfTypeToArray \main\corerun.exe Object 207.82 ns 1.00 160 B 1.00
OfTypeToArray \pr\corerun.exe Object 129.60 ns 0.62 152 B 0.95
OfTypeToList \main\corerun.exe Object 214.81 ns 1.00 264 B 1.00
OfTypeToList \pr\corerun.exe Object 158.42 ns 0.74 256 B 0.97
OfTypeFirst \main\corerun.exe Object 46.60 ns 1.00 88 B 1.00
OfTypeFirst \pr\corerun.exe Object 47.11 ns 1.01 80 B 0.91
OfTypeLast \main\corerun.exe Object 146.69 ns 1.00 88 B 1.00
OfTypeLast \pr\corerun.exe Object 72.18 ns 0.49 80 B 0.91
OfTypeSelectForEach \main\corerun.exe Object 172.42 ns 1.00 144 B 1.00
OfTypeSelectForEach \pr\corerun.exe Object 84.93 ns 0.49 104 B 0.72
OfTypeForEach \main\corerun.exe String 2,175.93 ns 1.00 88 B 1.00
OfTypeForEach \pr\corerun.exe String 1,046.87 ns 0.48 80 B 0.91
OfTypeCount \main\corerun.exe String 2,065.02 ns 1.00 88 B 1.00
OfTypeCount \pr\corerun.exe String 974.42 ns 0.47 80 B 0.91
OfTypeToArray \main\corerun.exe String 3,289.18 ns 1.00 1432 B 1.00
OfTypeToArray \pr\corerun.exe String 4,942.53 ns 1.50 1424 B 0.99
OfTypeToList \main\corerun.exe String 4,016.68 ns 1.00 4352 B 1.00
OfTypeToList \pr\corerun.exe String 2,926.28 ns 0.73 4344 B 1.00
OfTypeFirst \main\corerun.exe String 44.71 ns 1.00 88 B 1.00
OfTypeFirst \pr\corerun.exe String 31.20 ns 0.70 80 B 0.91
OfTypeLast \main\corerun.exe String 2,226.84 ns 1.00 88 B 1.00
OfTypeLast \pr\corerun.exe String 1,339.43 ns 0.59 80 B 0.91
OfTypeSelectForEach \main\corerun.exe String 2,689.61 ns 1.00 144 B 1.00
OfTypeSelectForEach \pr\corerun.exe String 1,150.00 ns 0.43 104 B 0.72
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Reflection;

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

[MemoryDiagnoser(false)]
[HideColumns("Job", "Error", "StdDev", "Median", "RatioSD")]
public partial class Tests
{
    private IEnumerable<MemberInfo> _members;

    [Params(typeof(object), typeof(string))]
    public Type Target { get; set; }

    [GlobalSetup]
    public void Setup() => _members = Target.GetMembers();

    [Benchmark]
    public int OfTypeForEach()
    {
        int sum = 0;
        foreach (MethodInfo member in _members.OfType<MethodInfo>())
        {
            sum += member.Name.Length;
        }
        return sum;
    }

    [Benchmark]
    public int OfTypeCount() => _members.OfType<MethodInfo>().Count();

    [Benchmark]
    public MethodInfo[] OfTypeToArray() => _members.OfType<MethodInfo>().ToArray();

    [Benchmark]
    public List<MethodInfo> OfTypeToList() => _members.OfType<MethodInfo>().ToList();

    [Benchmark]
    public MethodInfo OfTypeFirst() => _members.OfType<MethodInfo>().First();

    [Benchmark]
    public MethodInfo OfTypeLast() => _members.OfType<MethodInfo>().Last();

    [Benchmark]
    public int OfTypeSelectForEach()
    {
        int sum = 0;
        foreach (string name in _members.OfType<MethodInfo>().Select(m => m.Name))
        {
            sum += name.Length;
        }
        return sum;
    }
}

@stephentoub stephentoub added area-System.Linq tenet-performance Performance related issue labels Mar 4, 2024
@stephentoub stephentoub added this to the 9.0.0 milestone Mar 4, 2024
@ghost
Copy link

ghost commented Mar 4, 2024

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

Issue Details
Method Toolchain Target Mean Ratio Allocated Alloc Ratio
OfTypeForEach \main\corerun.exe Object 112.64 ns 1.00 88 B 1.00
OfTypeForEach \pr\corerun.exe Object 66.18 ns 0.59 80 B 0.91
OfTypeCount \main\corerun.exe Object 119.40 ns 1.00 88 B 1.00
OfTypeCount \pr\corerun.exe Object 101.25 ns 0.85 80 B 0.91
OfTypeToArray \main\corerun.exe Object 207.82 ns 1.00 160 B 1.00
OfTypeToArray \pr\corerun.exe Object 129.60 ns 0.62 152 B 0.95
OfTypeToList \main\corerun.exe Object 214.81 ns 1.00 264 B 1.00
OfTypeToList \pr\corerun.exe Object 158.42 ns 0.74 256 B 0.97
OfTypeFirst \main\corerun.exe Object 46.60 ns 1.00 88 B 1.00
OfTypeFirst \pr\corerun.exe Object 47.11 ns 1.01 80 B 0.91
OfTypeLast \main\corerun.exe Object 146.69 ns 1.00 88 B 1.00
OfTypeLast \pr\corerun.exe Object 72.18 ns 0.49 80 B 0.91
OfTypeSelectForEach \main\corerun.exe Object 172.42 ns 1.00 144 B 1.00
OfTypeSelectForEach \pr\corerun.exe Object 84.93 ns 0.49 104 B 0.72
OfTypeForEach \main\corerun.exe String 2,175.93 ns 1.00 88 B 1.00
OfTypeForEach \pr\corerun.exe String 1,046.87 ns 0.48 80 B 0.91
OfTypeCount \main\corerun.exe String 2,065.02 ns 1.00 88 B 1.00
OfTypeCount \pr\corerun.exe String 974.42 ns 0.47 80 B 0.91
OfTypeToArray \main\corerun.exe String 3,289.18 ns 1.00 1432 B 1.00
OfTypeToArray \pr\corerun.exe String 4,942.53 ns 1.50 1424 B 0.99
OfTypeToList \main\corerun.exe String 4,016.68 ns 1.00 4352 B 1.00
OfTypeToList \pr\corerun.exe String 2,926.28 ns 0.73 4344 B 1.00
OfTypeFirst \main\corerun.exe String 44.71 ns 1.00 88 B 1.00
OfTypeFirst \pr\corerun.exe String 31.20 ns 0.70 80 B 0.91
OfTypeLast \main\corerun.exe String 2,226.84 ns 1.00 88 B 1.00
OfTypeLast \pr\corerun.exe String 1,339.43 ns 0.59 80 B 0.91
OfTypeSelectForEach \main\corerun.exe String 2,689.61 ns 1.00 144 B 1.00
OfTypeSelectForEach \pr\corerun.exe String 1,150.00 ns 0.43 104 B 0.72
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Reflection;

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

[MemoryDiagnoser(false)]
[HideColumns("Job", "Error", "StdDev", "Median", "RatioSD")]
public partial class Tests
{
    private IEnumerable<MemberInfo> _members;

    [Params(typeof(object), typeof(string))]
    public Type Target { get; set; }

    [GlobalSetup]
    public void Setup() => _members = Target.GetMembers();

    [Benchmark]
    public int OfTypeForEach()
    {
        int sum = 0;
        foreach (MethodInfo member in _members.OfType<MethodInfo>())
        {
            sum += member.Name.Length;
        }
        return sum;
    }

    [Benchmark]
    public int OfTypeCount() => _members.OfType<MethodInfo>().Count();

    [Benchmark]
    public MethodInfo[] OfTypeToArray() => _members.OfType<MethodInfo>().ToArray();

    [Benchmark]
    public List<MethodInfo> OfTypeToList() => _members.OfType<MethodInfo>().ToList();

    [Benchmark]
    public MethodInfo OfTypeFirst() => _members.OfType<MethodInfo>().First();

    [Benchmark]
    public MethodInfo OfTypeLast() => _members.OfType<MethodInfo>().Last();

    [Benchmark]
    public int OfTypeSelectForEach()
    {
        int sum = 0;
        foreach (string name in _members.OfType<MethodInfo>().Select(m => m.Name))
        {
            sum += name.Length;
        }
        return sum;
    }
}
Author: stephentoub
Assignees: -
Labels:

area-System.Linq, tenet-performance

Milestone: 9.0.0

@ghost ghost assigned stephentoub Mar 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Linq tenet-performance Performance related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants