At production server, I have a simple code
mSocket.ReceiveFrom(mBuffer, SocketFlags.None, ref ep);
I call this code every millisecond. Recently I found out that almost 40% of allocations from my application are from this code. And all of the allocations are only 3 primitives: SocketAddress, IPEndPoint, IPAdress. It seems wasteful. Maybe I do something wrong? Can I read data from the UDP socket without this allocations? Can I have managed UDP transport with zero allocations?
Simple reproduction https://github.com/kripergvg/UdpAllocations
dotmemory after 4 minutes

ReceiveFrom variants have a surprisingly large number of allocations right now. This is likely to have a significant impact on QUIC. Seems worth a look at what we can do to improve things.
What do you think of adding some APIs to use SocketAddress directly:
```c#
class Socket
{
public int SendTo(ReadOnlySpan
public ValueTask
public int ReceiveFrom(Span<byte> buffer, SocketFlags socketFlags, SocketAddress remoteAddress);
public ValueTask<int> ReceiveFromAsync(Memory<byte> buffer, SocketFlags socketFlags, SocketAddress remoteAddress);
}
As well as some changes to conveniently access the result:
```c#
class SocketAddress
{
public ReadOnlyMemory<byte> IPAddress { get; }
public int Port { get; }
}
I wrote a quick proof of concept to test this.
Before:

After:

For a loop of 200,000 send/recv between 10 clients and 1 server, we remove about 2,200,000 allocations, and go from 12 GCs down to 0.
What do you think of adding some APIs to use
SocketAddressdirectly:class Socket { public int SendTo(ReadOnlySpan<byte> buffer, SocketFlags socketFlags, SocketAddress remoteAddress); public ValueTask<int> SendToAsync(ReadOnlyMemory<byte> buffer, SocketFlags socketFlags, SocketAddress remoteAddress); public int ReceiveFrom(Span<byte> buffer, SocketFlags socketFlags, SocketAddress remoteAddress); public ValueTask<int> ReceiveFromAsync(Memory<byte> buffer, SocketFlags socketFlags, SocketAddress remoteAddress); }As well as some changes to conveniently access the result:
class SocketAddress { public ReadOnlyMemory<byte> IPAddress { get; } public int Port { get; } }
Looking amazing. It would solve my problem.
Duplicate of dotnet/corefx#40933
Most helpful comment
I wrote a quick proof of concept to test this.
Before:

After:

For a loop of 200,000 send/recv between 10 clients and 1 server, we remove about 2,200,000 allocations, and go from 12 GCs down to 0.