-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Optimize unboxing in System.Data.Common.ObjectStorage:Set
#91945
Conversation
Tagging subscribers to this area: @roji, @ajcvickers Issue DetailsEmitting
|
{ | ||
_values[recordNo] = new Guid((string)value); | ||
} | ||
else if (_dataType == typeof(byte[])) | ||
{ | ||
if (valType == typeof(bool)) | ||
if (value is bool) |
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.
nit: can use a switch expression
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.
This may hit the performance issue logged in #47920. I actually have a branch to improve this, but it's not expandable-proof so I haven't push it.
It's also interesting to see if a following unbox.any
changes the codegen of isinst
.
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.
In the case of a switch expression, the JIT is not able to eliminate the calls to CORINFO_HELP_UNBOX
.
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'm surprised that CORINFO_HELP_UNBOX
is ever evolved after #87241.
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'm surprised that
CORINFO_HELP_UNBOX
is ever evolved after #87241.
The isinst
+ unbox.any
optimization appears in .NET 7.
there should be no perf difference between |
This is part of the current codegen, from the build MihuBot/runtime-utils#177, showing a call to G_M32004_IG28:
mov rsi, 0xD1FFAB1E ; 'System.UInt64'
cmp rax, rsi
jne SHORT G_M32004_IG31
mov r15, gword ptr [r15+0x40]
mov rsi, 0xD1FFAB1E ; System.UInt64
cmp qword ptr [rbx], rsi
je SHORT G_M32004_IG30
;; size=34 bbWeight=0.50 PerfScore 3.88
G_M32004_IG29:
mov rsi, rbx
mov rdi, 0xD1FFAB1E ; System.UInt64
mov rax, 0xD1FFAB1E ; code for CORINFO_HELP_UNBOX
call [rax]CORINFO_HELP_UNBOX
;; size=25 bbWeight=0.25 PerfScore 0.94
G_M32004_IG30:
mov rdi, qword ptr [rbx+0x08]
mov rax, 0xD1FFAB1E ; code for System.BitConverter:GetBytes(ulong):ubyte[]
call [rax]System.BitConverter:GetBytes(ulong):ubyte[]
mov rdx, rax
movsxd rsi, r14d
mov rdi, r15
call CORINFO_HELP_ARRADDR_ST
jmp G_M32004_IG37
;; size=35 bbWeight=0.50 PerfScore 4.50
|
@EgorBo This change is also a little more efficient in terms of IL.
vs:
|
I think we would be able to use |
`System.ArgumentException : Type of value has a mismatch with column typeCouldn't store <System.Int32[]> in Column1 Column. Expected type is Array.`
if (_nullValue == value) | ||
{ | ||
_values[recordNo] = null; | ||
return; |
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.
What is the aim behind replacing else
blocks with many duplicated return
s?
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.
To use a single throw at the end of the method whilst keeping the control flow simple. The JIT will create a single exit.
If this is less readable I can revert to else
blocks.
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.
@MihaZupan What is your view on this?
isinst
in System.Data.Common.ObjectStorage:Set
System.Data.Common.ObjectStorage:Set
@EgorBo This is correct, as long as I've refactored to use |
Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it. |
Inline
value.GetType()
instead of using a local, to enable a JIT optimization.Diffs: https://www.diffchecker.com/QgpKJ9UD/