-
Notifications
You must be signed in to change notification settings - Fork 299
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
Performance and async improvements in SSRP, connection establishment and MARS connections #2451
Conversation
This isn't in use yet, but once TCP connection establishment is fully async, it'll be available. Also incremented the version of BenchmarkDotNet (so that the benchmarks can run with .NET 8.0.)
Made the various fields strongly-typed to eliminate casting/parsing on the hot path.
This removes an explicit task continuation, slightly reduces memory usage and makes use of the newer .NET 6.0+ APIs to simplify socket connection cancellation
* Forcing the flush of all streams before they get switched over to SSL/TLS streams. * Forcing the task sending the pre-login packet to be sent before we try to process the response. Minor tweaks here: * Removed two copies from SSRP. * Switched a few instances of manual bit-shifting to .NET intrinsics.
If an SNINetworkStream is wrapped by an SNISslStream, there's already a layer of synchronisation - we don't need to keep the inner one enabled.
* The SNI SMUX header is now a ref struct * Now using intrinsics to write out the message header Also updated the reading of header lengths to use intrinsics.
Also corrected runnerconfig to allow it to bypass SSL verification by default (for default localhost usage.)
…SNIMarsHeader struct rather than reading into it. Also caching UdpClient instances on a per-AddressFamily basis to prevent reallocating them for the same family. Removed the instantiation of one delegate instance to reduce memory usage slightly.
One exception to this is that we're writing a byte array rather than a span to the packet - TdsParserStateObject doesn't support it there
Removing one implicit string allocation if a UDP request fails and tracing is disabled.
This commit lays the groundwork to eliminate the second DNS lookup required after SSRP.
If a DNS lookup was needed for SSRP, forward its results to the TCP connection creation
Can you share some benchmark results? |
SSRP timeout returns an OperationCanceledException inside an AggregateException
The absolute difference in result times is pretty minor - it's around a 10% reduction in an execution time of 2-2.5ms. On average memory usage has dropped by around 3-4KB. No multi-subnet failoverBaseline
Post changes
Multi-subnet failoverBaseline
Post changes
I have the other benchmarks across local instances (named and default), and Azure SQL instances (within the same region and in a distant region), but they're broadly similar: small memory usage improvements when connecting, and minor variations in execution times which are within the specified margin of error. I've not included these because of volume: there's one for every combination of [baseline/updated, multi-subnet failover enabled/disabled, managed/native SNI] on each of the SQL instances. |
One pre-existing issue with a resource string missing a space. Several instances where the SQL DNS cache property names were hardcoded and accessed via reflection.
The current header is now an instance-level variable once again. Not sure why this would make a difference, but without this, some of the data bytes are left in the packet buffer and interpreted as the header bytes of the next packet.
…gle IP address. Correcting a deadlock in MARS connection tests.
I've just noticed this PR's attached to the preview2 milestone. Could it be removed please? It's quite out-of-date, and I think it'd be easier to split these changes into a handful of smaller ones:
|
This PR eliminates sync-over-async in SSRP, starts to simplify TCP connection establishment in the managed SNI provider by using async/await and slightly improves performance when building the pre-login packet. It lays some infrastructure down for PR #2384, although TdsParser would probably need to be merged before opening a connection can be made fully asynchronous.
SNIMarsHandle._callbackObject
on the hot path - declared it as TdsParserStateObject.I also noticed while benchmarking that the benchmarking project didn't run on .NET 8.0, so I've bumped the version of BenchmarkDotNet to one which supports this.
Edit: I can see a number of test failures - will re-run them locally and resolve.