- Notifications
You must be signed in to change notification settings - Fork311
Merge | SniNativeWrapper Interface#3015
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
codecovbot commentedNov 18, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@## main #3015 +/- ##===========================================- Coverage 92.58% 72.72% -19.86%=========================================== Files 6 283 +277 Lines 310 58975 +58665 ===========================================+ Hits 287 42892 +42605- Misses 23 16083 +16060
Flags with carried forward coverage won't be shown.Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I was actually wondering how we were going to approach this merge. I've only got a few comments on the way the PR handles the approach, but are there any wider plans to merge the references to the two native SNI packages?
Although I can't speak in specifics, when comparing the performance of a switch per call and calling an interface which calls the method, the interface approach is significantly more performant.
That's true in this case, but the JIT will also make its presence felt.RuntimeInformation.ProcessArchitecture
is a constant expression at runtime, so the JIT will see a switch with a constant expression and optimise it away. On .NET Core, you might not actually have a switch expression at all.
src/Microsoft.Data.SqlClient/netcore/src/Interop/SNINativeMethodWrapper.Windows.cs OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Interop/SNINativeMethodWrapper.cs OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
src/Microsoft.Data.SqlClient/src/Interop/Windows/Sni/SniNativeMethodsArm64.netfx.cs OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
469f92a
to4eb92bf
CompareThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
LGTM
4eb92bf
to696c949
Compare46e8714
intodotnet:mainUh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Description: This is part 2 of 2 for merging SNI native method wrappers. It's a little more involved than before and requires a bit of explanation.
In the netfx version of the SNI native wrapper, the SniNativeWrapper class is truly a wrapper around three native libraries (x86, x64, and arm64). The prior code for this had a switch on each case that would check the architecture of the system and call the appropriate native library. This isn't ideal since it requires a switch statement each time a native SNI call is made. A better approach would be to have the wrapper call into a native library that is picked at static construction of the wrapper.
However, there are limitations to this approach:
[DllImport]
dll. However, this must be a compile time constant. This means there must be a class for each of the native libraries.[DllImport]
, the method must beextern
, which must bestatic
. Interfaces cannot have static methods (at least not prior to net7, iirc), so in order for the library classes to implement an interface, they have to have an instance method that calls into the static, extern method.Thus, here is the class hierarchy:
SNINativeMethodWrapper
[netfx],SNINativeMethodWrapper.Windows
[netcore]ISniNativeWrapper
[netfx, netcore]SniNativeMethods
[netcore]SniNativeMethodsArm64
[netfx]SniNativeMethodsNotSupported
[netfx] - used when architecture is not supportedSniNativeMethodsX64
[netfx]SniNativeMethodsX86
[netfx]Although I can't speak in specifics, when comparing the performance of a switch per call and calling an interface which calls the method, the interface approach is significantly more performant. (sorry@David-Engel )
Testing: For the most part, this just moves code around and doesn't really change the functionality. Everythingshould still work, but the native SNI CI tests will confirm.