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

Add optimized path for IReadOnlyCollection/IReadOnlyList in System.Linq #23910

Closed
huoyaoyuan opened this issue Oct 20, 2017 · 10 comments
Closed
Labels
area-System.Linq enhancement Product code improvement that does NOT require public API changes/additions help wanted [up-for-grabs] Good issue for external contributors tenet-performance Performance related issue
Milestone

Comments

@huoyaoyuan
Copy link
Member

It's kind of historical reason for the readonly interfaces not inherited by ICollection<T>/IList<T>.
Adding a optimized path needs a copy of all ICollection<T>/IList<T> paths and classes.
Implementing ICollection<T> with IsReadOnly = true does get the optimizations, but it's kind of violating the interfaces.

@stephentoub
Copy link
Member

Optimized path in what? What optimizations? What's the scenario?

@huoyaoyuan
Copy link
Member Author

Sorry for forgetting type LINQ in the title.

@huoyaoyuan huoyaoyuan changed the title Add optimized path for IReadOnlyCollection/IReadOnlyList Add optimized path for IReadOnlyCollection/IReadOnlyList in System.Linq Oct 20, 2017
@molinch
Copy link

molinch commented Feb 13, 2018

@stephentoub @huoyaoyuan It's not just about Linq but also in many other areas like: List.InsertRange, see: http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,711

If you give an IReadOnlyCollection, and that instance does not implement ICollection too, it will then instanciate an Enumerator and iterate, otherwise it could be super optimized.
However that's a very minor issue since BCL types implement ICollection, so it's only if you roll your own that you may get this problem.

By the way, shouldn't ICollection implement IReadOnlyCollection? Then less code would need to touched: we would only need to change the cast to IReadOnlyCollection here.

@stephentoub
Copy link
Member

It's not just about Linq but also in many other areas like: List.InsertRange [...] otherwise it could be super optimized [...]

Yes. But adding that IReadOnlyCollection<T> type check is an expense that's paid for all enumerables, not just IReadOnlyCollection<T>. As with many optimizations, you make some things faster at the expense of making other things slower, and the upside needs to be worth the downside. As you pointed out, most enumerables in the core libraries that are IReadOnlyCollection<T> also implement other interfaces already optimized for, so the upside for the majority of collections people use is small. To take such a change, there'd need to be a solid set of data provided about what the positive and negative impacts would be and why it's worthwhile.

shouldn't ICollection implement IReadOnlyCollection?

It's actually a breaking change. See https://github.com/dotnet/corefx/issues/5489 for an example.

@molinch
Copy link

molinch commented Feb 13, 2018

Thanks @stephentoub for the quick feedback.
Couldn't what Nick shows be solved by the C# compiler?

Just another remark related to this, Array.cs doesn't implement IReadOnlyList neither IReadOnlyCollection. Would you accept a PR doing so?

@stephentoub
Copy link
Member

doesn't implement IReadOnlyList neither IReadOnlyCollection

Arrays do, they're just a very special type and the implementation is provided by the runtime, i.e. this works fine:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var data = new int[1] { 42 };
        IReadOnlyList<int> list = data;
        Console.WriteLine(list[0]);
    }
}

@molinch
Copy link

molinch commented Feb 13, 2018

That's interesting! I expected what is in Array.cs to be the source of truth.
Thanks a lot for the explanation.

@mattwarren
Copy link
Contributor

@molinch <shameless plug> if you want more info on this, see a blog post I wrote Arrays and the CLR - a Very Special Relationship, in particular the 'Implementation Details' section </shameless plug>

@molinch
Copy link

molinch commented Feb 14, 2018

Many things are much more clear, thanks @mattwar !
I love the sentence "Arrays are basically voodoo." hahaha

@stephentoub
Copy link
Member

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 5.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Linq enhancement Product code improvement that does NOT require public API changes/additions help wanted [up-for-grabs] Good issue for external contributors tenet-performance Performance related issue
Projects
None yet
Development

No branches or pull requests

5 participants