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

Suggestion to avoid allocations by passing delegate directly or lambda #3761

Closed
jnm2 opened this issue Dec 13, 2019 · 3 comments
Closed

Suggestion to avoid allocations by passing delegate directly or lambda #3761

jnm2 opened this issue Dec 13, 2019 · 3 comments

Comments

@jnm2
Copy link
Contributor

jnm2 commented Dec 13, 2019

The aim of dotnet/roslyn#40364 is simplification, while the aim of this alternative is performance.

denotes where the suggestion span would be and _ denotes the spans that would be faded as unnecessary.

class C
{
    // Changed to an instance method because of https://github.com/dotnet/roslyn/pull/58288
    bool IsEven(int x) => x % 2 == 0;

    void Example1()
    {
        // 💡 Avoid allocation by replacing method group with lambda
        //                          ↓↓↓↓↓↓
        _ = new[] { 1, 2, 3 }.Where(IsEven);

        // 🛠 Fix result:
        _ = new[] { 1, 2, 3 }.Where(n => IsEven(n));
    }

    void Example2()
    {
        var neverReassigned = new Func<int, bool>(IsEven);

        // 💡 Avoid allocation by replacing lambda with delegate
        //                          _____↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓___
        _ = new[] { 1, 2, 3 }.Where(n => neverReassigned(n));

        // 💡 Avoid allocation by replacing lambda with delegate
        //                          _____↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓__________
        _ = new[] { 1, 2, 3 }.Where(n => neverReassigned.Invoke(n));

        // 💡 Avoid allocation by replacing Invoke method group with delegate
        //                          ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓_______
        _ = new[] { 1, 2, 3 }.Where(neverReassigned.Invoke);


        // 🛠 Fix result:
        _ = new[] { 1, 2, 3 }.Where(neverReassigned);
    }

    void Example3()
    {
        var reassigned = new Func<int, bool>(IsEven);

        // No diagnostic
        _ = new[] { 1, 2, 3 }.Where(n => reassigned.Invoke(n));

        // 💡 Avoid allocation by replacing Invoke method group with delegate
        //                          ↓↓↓↓↓↓↓↓↓↓_______
        _ = new[] { 1, 2, 3 }.Where(reassigned.Invoke);

        reassigned = n => !IsEven(n);


        // 🛠 Fix result:
        _ = new[] { 1, 2, 3 }.Where(reassigned);
    }
}
@CyrusNajmabadi
Copy link
Member

@mavasani maybe port to roslyn-analyzers?

@mavasani mavasani transferred this issue from dotnet/roslyn Jun 19, 2020
@mavasani mavasani added this to the .NET 6.x milestone May 6, 2021
@jnm2
Copy link
Contributor Author

jnm2 commented Jan 15, 2022

Updated because of dotnet/roslyn#58288: now only instance method groups are per-call allocations.

@jnm2
Copy link
Contributor Author

jnm2 commented Jan 15, 2022

Oh, and then there's still no avoiding the allocation by using a lambda, so this issue is obsolete.

@jnm2 jnm2 closed this as completed Jan 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants