MichaCo / DnsClient.NET

DnsClient.NET is a simple yet very powerful and high performant open source library for the .NET Framework to do DNS lookups
https://dnsclient.michaco.net
Apache License 2.0
762 stars 136 forks source link

Reduce allocations #213

Closed antonfirsov closed 3 months ago

antonfirsov commented 4 months ago

I noticed some opportunities to significantly reduce the GC allocations done by the library, particularly:

  1. UdpClient allocates a new array on every receive, which is responsible for the vast majority of allocations done by the lib. Using Socket instead would enable pooling the receive buffer or even using stackalloc.
  2. PooledBytes is using a custom array pool. Using ArrayPool<byte>.Shared would enable better recycling of arrays between DnsClient.NET and other libraries including the BCL which uses the shared pool exclusively. Moreover, with some minor refactoring PooledBytes could be made a struct itself.

According to my experiments the improvement potential is huge.

Method Mean Error StdDev Gen0 Gen1 Allocated
QueryA 167.491 μs 52.8399 μs 2.8963 μs 6.5918 1.4648 69698 B
QueryAsyncA 258.315 μs 135.2620 μs 7.4142 μs 6.8359 1.4648 72325 B
Method Mean Error StdDev Gen0 Allocated
QueryA 164.565 μs 82.1385 μs 4.5023 μs 0.2441 3955 B
QueryAsyncA 249.002 μs 75.6773 μs 4.1481 μs 0.4883 6407 B

If you are interested taking the suggested changes, I can create a PR in the coming weeks.

MichaCo commented 4 months ago

Hey Anton, For the first part, I was actually using socket directly for the longest time. I just recently changed the implementation to use UdpClient directly because there is actually a memory leak when using Socket directly under full framework only (net4.8 for example). see #192 That scared me a bit because I couldn't really figure out a good fix or workaround either.

Those changes are not release yet, so if you have an idea, let me know!

Regarding part 2) Yeah I think you are right, we should change it to use the shared array pool.

Regarding a PR, yeah go for it, I'm eager to see what you have in mind.