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 new overloads with ReadOnlySpan to System.Net.NetworkInformation.PhysicalAddress #26214

Closed
iSazonov opened this issue May 18, 2018 · 9 comments
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-System.Net
Milestone

Comments

@iSazonov
Copy link
Contributor

Rationale

Coming from #26188.

Let's to consider a scenario of DHCP log parsing. We read line by line and parse the line to get fields. Previously we used Substring() method. My understanding is that now best practice (from Stephen Toub) is to use Slice() to exclude extra allocations. So suggested overloads with ReadOnlySpan can be useful.

It is very perf-sensitive - sizes of DHCP logs can reach huge sizes in enterprises. We could use perl or php (or sed/awk) but why we should refuse favourite C# and PowerShell?

About "The API is rare". (1) Although it is rare but we all already have this Parse (string address); - why if it is rare? (2) Why such APIs should remain not optimized? Adding and having ReadOnlySpan overloads is too expensive? I'd like to see a policy and guidance from your team.

Proposed API

namespace System.Net.NetworkInformation
{
    public class PhysicalAddress
    {
        public static bool TryParse(string address, out PhysicalAddress value);
        public static bool TryParse(ReadOnlySpan<char> address, out PhysicalAddress value);
        public static PhysicalAddress Parse(ReadOnlySpan<char> address);
        // Existing
        // public static PhysicalAddress Parse(string address);
    }
}
@ghost
Copy link

ghost commented May 18, 2018

Would it make sense to move public static bool TryParse(string address, out PhysicalAddress mac); to this proposal as well and leave #26188 scoped to improve the parsing logic?

@karelz
Copy link
Member

karelz commented May 18, 2018

IMO we should not merge TryParse into this API request. TryParse is about avoiding exceptions in non-exceptional cases. Span is about critical perf.

@karelz
Copy link
Member

karelz commented May 18, 2018

(1) Although it is rare but we all already have this Parse (string address); - why if it is rare?

We have Parse API, because it is sometimes (albeit rarely) useful. Having the capability is valuable (as its usage shows), but it in general does not justify to have the capability hyper-optimized, especially when the optimization is not free (adding new API).

(2) Why such APIs should remain not optimized? Adding and having ReadOnlySpan overloads is too expensive? I'd like to see a policy and guidance from your team.

Adding API is not free. It has cost also on platform usability (choice from more overloads adds tax on developers).
AFAIK so far we added Span overloads only to types where we saw clear perf benefits in perf-sensitive scenarios (e.g. web servers). We held back on the rest. We may reconsider that in future and adjust our position.

Personally, I am skeptical that the Span overloads would help to make any real-world DHCP parser app measurably faster. It feels more like premature optimization to me, but maybe I am wrong about it or there are other scenarios where it matters.

On related note: If there was no Parse API at all and we would be adding it from scratch - would we choose string or ReadOnlySpan<char>? ... I am not sure even about that, given that it is not high-performance parser. For me the simplicity and familiarity of string would probably win over potential perf advantage.

@ghost
Copy link

ghost commented May 19, 2018

IMO we should not merge TryParse into this API request. TryParse is about avoiding exceptions in non-exceptional cases. Span is about critical perf.

Then TryParse maybe doesn't belong to https://github.com/dotnet/corefx/issues/29740 either, rather than in its own proposal. This proposal is about Parse and TryParse overloads, where the latter one doesn't exist. So that should be reworded as well, right?

@iSazonov
Copy link
Contributor Author

@karelz Thanks for sharing .Net Core team policy!

Adding API is not free.

I agree that the choice of a large number of APIs adds complexity for developers. But really this complication appears if similar things are done in different places (namespaces).
My point is that Spans is a special case - we do not add new APIs, we make a mirror of the existing ones. I would expect that such Span overloads exist for most existing string APIs.
The point comes from PowerShell Core engine code analyses. PowerShell likes to convert everything into strings. So the more APIs have Spans the faster the engine we can make. (This is certainly a generalization).
PowerShell can't use Spans in scripts but PowerShell can do a lot of magical things. For example, it allows you to delegate script blocks. If we learn how to use Spans there, our users will be able to create much more efficient scripts, but only if APIs similar to those discussed in this topic will have Spans overloads.

@iSazonov
Copy link
Contributor Author

@kasper3

This proposal is about Parse and TryParse overloads , where the latter one doesn't exist

I believe the topic is a successor of #26188 - if #26188 will be rejected the suggestion will be rejected too. In any case I agree to reword. Feel free to edit the issue description.

@karelz
Copy link
Member

karelz commented Oct 1, 2019

Triage: Networking team is fine to take these APIs for larger review.

@terrajobst
Copy link
Member

terrajobst commented Oct 22, 2019

Video

We should also have string-based TryParse method. We should also name the out parameter value. Other than that, looks good as proposed.

namespace System.Net.NetworkInformation
{
    public class PhysicalAddress
    {
        public static bool TryParse(string address, out PhysicalAddress value);
        public static bool TryParse(ReadOnlySpan<char> address, out PhysicalAddress value);
        public static PhysicalAddress Parse(ReadOnlySpan<char> address);
        // Existing
        // public static PhysicalAddress Parse(string address);
    }
}

@alnikola alnikola self-assigned this Dec 18, 2019
@MihaZupan
Copy link
Member

@terrajobst What is the use-case for a string-based TryParse if we're adding a ROS<cbar> overload?

alnikola referenced this issue Jan 7, 2020
This PR introduces two new PhysicalAddress.TryParse methods taking span and string as well as adds a PhysicalAddress.Parse overload taking span.
Fixes dotnet/corefx#29780
@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 5.0 milestone Jan 31, 2020
@dotnet dotnet locked as resolved and limited conversation to collaborators Dec 16, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Net
Projects
None yet
Development

No branches or pull requests

6 participants