-
Notifications
You must be signed in to change notification settings - Fork 314
SqlMetadataPrivFlags remove Enum.HasFlag in favor of bitwise operations #1054
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
Conversation
Please also update the same for other flags while you're at it. |
Netcore or netfx? because in netcore I was specifically advised to use Enum.HasFlag because it's intrinsic and the compiler should recognise it and emit good assembly. |
Yeah, Enum.HasFlag is indeed recommended in .NET Core. Anyone using .NET Framework at this point can't really care that much about high-perf, given the huge gaps between Framework and Core. |
@roji @Wraith2 I'm seeing the allocations from SqlMetadataPriv.GetNullable (Enum.GetFlag) occur in the JetBrains DotTrace TimeLine Profiler while running I did a quick benchmark and you guys are correct - it does not seem to be allocating in my corporate .NET 5 application: BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.1500 (1909/November2018Update/19H2)
Intel Xeon E-2176M CPU 2.70GHz, 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=5.0.202
[Host] : .NET Core 5.0 (CoreCLR 5.0.521.16609, CoreFX 5.0.521.16609), X64 RyuJIT
Job=InProcess Toolchain=InProcessEmitToolchain
I also checked .NET core 3.1 and results were good there too. I guess i'm still confused why it's showing up in |
I've thought this thought a bit. The PR's when I was changing this are when I was working on System.Data.SqlClient in the corefx repository and at that time the only target was netcore and it made sense to use HasFlag because it's simpler and had been fixed for netcore not to have bad codegen. Working on Microsoft.Data.SqlClient is different because we've got the netfx codebase to think about and one of the long term goals here is to unify as much code as possible between the two so that netfx perf improves wherever possible alongside the direct target of netcore. Codegen on netcore between the two is similar enough that it's unlikely to be the cause of a major performance disruption to use masking on netcore. So HasFlag was the correct choice when it was made but direct masking is now the correct choice and I think that should be the overall policy in this codebase. I'll try to incorporate that into my future PR's as well. |
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.
LGTM
@cmeyertons would you be able to address this small request soon? |
I can pick up that change in a separate PR if that's easier. |
@cheenamalhotra @Wraith2 earliest I can get back to this is Monday :/ |
FYI - I've updated the PR with additional changes to unblock from review. |
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.
Could you update the Updateability
to use the related enum member instead of 0x3
?
public byte Updatability
{
get => (byte)(flags & _SqlMetadataFlags.IsUpdatableMask);
set => flags = (_SqlMetadataFlags)((value & (byte)_SqlMetadataFlags.IsUpdatableMask) | ((int)flags & (int)~_SqlMetadataFlags.IsUpdatableMask));
}
Noticed this in the profiler -- IsNullable was allocating the enum struct because of Enum.HasFlag
There's pretty wide spread usage of Enum.HasFlag throughout the repo, but this is the only one occurring in the SqlBulkCopy critical path.