C# 实施和履行;是T x“;对于值类型
我有类似的情况:C# 实施和履行;是T x“;对于值类型,c#,.net,cil,C#,.net,Cil,我有类似的情况: interface IStorage { bool TryGetValue<T>(out T result) where T : struct; } class Storage<T> : IStorage where T : struct { readonly T value; public Storage(T val) { value = val; } public bool Try
interface IStorage
{
bool TryGetValue<T>(out T result) where T : struct;
}
class Storage<T> : IStorage where T : struct
{
readonly T value;
public Storage(T val)
{
value = val;
}
public bool TryGetValue<T2>(out T2 result) where T2 : struct
{
if(value is T2 val)
{
result = val;
return true;
}
result = default;
return false;
}
}
结果表明,表达式不仅一次,而且两次将值装箱,isinst
的第一次和unbox.any
的第二次,因此它不仅隐藏装箱(通常认为很昂贵),而且还隐藏了两次
我有两个问题:有没有更好的方法来实现这种专业化?这段CIL代码虽然看起来效率很低,但是否有可能在以后的运行时通过JIT进行优化
在这种特殊情况下,我希望运行时推断出T
为T2
的唯一实例化应该返回true,并且应该忽略所有其他代码,包括检查。可能是这种情况吗?“这段CIL代码虽然看起来效率很低,但是否有可能在稍后的运行时通过JIT进行优化?”-不,JIT代码的结果似乎也很臃肿,但需要更多的测试来验证。我的小型4.8框架编译if(值为t2val)
to
00007FFDEF110E3D mov rdx,qword ptr [rbp+90h]
00007FFDEF110E44 add rdx,8
00007FFDEF110E48 vmovdqu xmm0,xmmword ptr [rdx]
00007FFDEF110E4D vmovdqu xmmword ptr [rbp+40h],xmm0
00007FFDEF110E53 lea rdx,[rbp+40h]
00007FFDEF110E57 mov rcx,7FFDEF006C68h
00007FFDEF110E61 call 00007FFE4E642570
00007FFDEF110E66 mov qword ptr [rbp+30h],rax
00007FFDEF110E6A mov rdx,qword ptr [rbp+30h]
00007FFDEF110E6E mov rcx,7FFDEF006C68h
00007FFDEF110E78 call 00007FFE4E643D00
00007FFDEF110E7D test rax,rax
00007FFDEF110E80 je 00007FFDEF110ED7
00007FFDEF110E82 lea rdx,[rbp+40h]
00007FFDEF110E86 mov rcx,7FFDEF006C68h
00007FFDEF110E90 call 00007FFE4E642570
00007FFDEF110E95 mov qword ptr [rbp+28h],rax
00007FFDEF110E99 mov rdx,qword ptr [rbp+28h]
00007FFDEF110E9D mov rcx,7FFDEF006C68h
00007FFDEF110EA7 call 00007FFE4E643D00
00007FFDEF110EAC mov qword ptr [rbp+20h],rax
00007FFDEF110EB0 mov rdx,qword ptr [rbp+20h]
00007FFDEF110EB4 mov rcx,7FFDEF006C68h
00007FFDEF110EBE call 00007FFE4E6BC030
00007FFDEF110EC3 vmovdqu xmm0,xmmword ptr [rax]
00007FFDEF110EC8 vmovdqu xmmword ptr [rbp+58h],xmm0
00007FFDEF110ECE mov dword ptr [rbp+38h],1
00007FFDEF110ED5 jmp 00007FFDEF110EDC
00007FFDEF110ED7 xor eax,eax
00007FFDEF110ED9 mov dword ptr [rbp+38h],eax
00007FFDEF110EDC mov eax,dword ptr [rbp+38h]
00007FFDEF110EDF movzx eax,al
00007FFDEF110EE2 mov dword ptr [rbp+54h],eax
00007FFDEF110EE5 cmp dword ptr [rbp+54h],0
00007FFDEF110EE9 je 00007FFDEF110F08
这是使用ValueType的一个限制条件——这样的操作会变得一团糟。如果这是一个常见的用例,也许这不应该是一个结构?您有性能问题吗?您是否希望在性能关键的情况下使用此方法?因为如果不是,那么这就是过早的优化。我不是100%确定,但是由于.net c#jit单独发出泛型代码,并且jit可以检查这个条件,所以应该从输出中忽略它。因此,我认为检查不会在运行时执行,对性能没有影响
00007FFDEF110E3D mov rdx,qword ptr [rbp+90h]
00007FFDEF110E44 add rdx,8
00007FFDEF110E48 vmovdqu xmm0,xmmword ptr [rdx]
00007FFDEF110E4D vmovdqu xmmword ptr [rbp+40h],xmm0
00007FFDEF110E53 lea rdx,[rbp+40h]
00007FFDEF110E57 mov rcx,7FFDEF006C68h
00007FFDEF110E61 call 00007FFE4E642570
00007FFDEF110E66 mov qword ptr [rbp+30h],rax
00007FFDEF110E6A mov rdx,qword ptr [rbp+30h]
00007FFDEF110E6E mov rcx,7FFDEF006C68h
00007FFDEF110E78 call 00007FFE4E643D00
00007FFDEF110E7D test rax,rax
00007FFDEF110E80 je 00007FFDEF110ED7
00007FFDEF110E82 lea rdx,[rbp+40h]
00007FFDEF110E86 mov rcx,7FFDEF006C68h
00007FFDEF110E90 call 00007FFE4E642570
00007FFDEF110E95 mov qword ptr [rbp+28h],rax
00007FFDEF110E99 mov rdx,qword ptr [rbp+28h]
00007FFDEF110E9D mov rcx,7FFDEF006C68h
00007FFDEF110EA7 call 00007FFE4E643D00
00007FFDEF110EAC mov qword ptr [rbp+20h],rax
00007FFDEF110EB0 mov rdx,qword ptr [rbp+20h]
00007FFDEF110EB4 mov rcx,7FFDEF006C68h
00007FFDEF110EBE call 00007FFE4E6BC030
00007FFDEF110EC3 vmovdqu xmm0,xmmword ptr [rax]
00007FFDEF110EC8 vmovdqu xmmword ptr [rbp+58h],xmm0
00007FFDEF110ECE mov dword ptr [rbp+38h],1
00007FFDEF110ED5 jmp 00007FFDEF110EDC
00007FFDEF110ED7 xor eax,eax
00007FFDEF110ED9 mov dword ptr [rbp+38h],eax
00007FFDEF110EDC mov eax,dword ptr [rbp+38h]
00007FFDEF110EDF movzx eax,al
00007FFDEF110EE2 mov dword ptr [rbp+54h],eax
00007FFDEF110EE5 cmp dword ptr [rbp+54h],0
00007FFDEF110EE9 je 00007FFDEF110F08