Aid*_*api 3 c# performance casting unsafe
我知道标题有点模糊.但我想要实现的是这样的:
在抽象类中:
public abstract bool TryGet<T>(string input, out T output) where T : struct;
Run Code Online (Sandbox Code Playgroud)
在具有此签名的类中:
private class Param<T> : AbstractParam where T : struct
Run Code Online (Sandbox Code Playgroud)
这个实现:
public override bool TryGetVal<TOriginal>(string input, out TOriginal output)
{
T oTemp;
bool res = _func(input, out oTemp); // _func is the actual function
// that retrieves the value.
output = (TOriginal)oTemp; // Compile-time error
return res;
}
Run Code Online (Sandbox Code Playgroud)
而且TOriginal将永远是相同的类型T.这会绕过编译时错误,但我不想这样做会导致性能下降:
output = (TOriginal)(object)oTemp;
Run Code Online (Sandbox Code Playgroud)
如果它是引用类型,这将提供解决方案:
output = oTemp as TOriginal;
Run Code Online (Sandbox Code Playgroud)
反射/动态也可以解决问题,但性能影响更大:
output = (TOriginal)(dynamic)oTemp;
Run Code Online (Sandbox Code Playgroud)
我尝试使用不安全的代码,但没有成功,但那可能只是我.
所以,我的最大希望是,编译器优化要么(TOriginal)(object)oTemp对(TOriginal)oTemp,我不知道.或者说这是一个不安全的方法.
拯救我关于过早优化的讲座,我想知道这纯粹是为了研究,并且有兴趣是否有办法克服这个限制.我意识到这对实际表现的影响可以忽略不计.
最终结论:
在拆解情况后,结果如下:
return (TOut)(object)_value;
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 mov dword ptr [ebp-4],ecx
00000007 cmp dword ptr ds:[003314CCh],0
0000000e je 00000015
00000010 call 61A33AD3
00000015 mov eax,dword ptr [ebp-4]
00000018 mov eax,dword ptr [eax+4]
0000001b mov esp,ebp
0000001d pop ebp
0000001e ret
return _value;
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 mov dword ptr [ebp-4],ecx
00000007 cmp dword ptr ds:[004814B4h],0
0000000e je 00000015
00000010 call 61993AA3
00000015 mov eax,dword ptr [ebp-4]
00000018 mov eax,dword ptr [eax+4]
0000001b mov esp,ebp
0000001d pop ebp
0000001e ret
Run Code Online (Sandbox Code Playgroud)
事实证明,今天的编译器对此进行了优化,因此没有性能成本.
output = (TOriginal)(object)oTemp;
Run Code Online (Sandbox Code Playgroud)
这是最优化的方式:).
关于引用类型的注释:
删除struct约束并传递引用类型(在我的情况下为a string)时,不会进行此优化.
结果:
return (TOut)(object)_value;
00000000 push ebp
00000001 mov ebp,esp
00000003 sub esp,10h
00000006 mov dword ptr [ebp-4],edx
00000009 mov dword ptr [ebp-10h],ecx
0000000c mov dword ptr [ebp-8],edx
0000000f cmp dword ptr ds:[003314B4h],0
00000016 je 0000001D
00000018 call 61A63A43
0000001d mov eax,dword ptr [ebp-8]
00000020 mov eax,dword ptr [eax+0Ch]
00000023 mov eax,dword ptr [eax]
00000025 mov dword ptr [ebp-0Ch],eax
00000028 test dword ptr [ebp-0Ch],1
0000002f jne 00000036
00000031 mov ecx,dword ptr [ebp-0Ch]
00000034 jmp 0000003C
00000036 mov eax,dword ptr [ebp-0Ch]
00000039 mov ecx,dword ptr [eax-1]
0000003c mov eax,dword ptr [ebp-10h]
0000003f mov edx,dword ptr [eax+4]
00000042 call 617D79D8
00000047 mov esp,ebp
00000049 pop ebp
0000004a ret
return _value;
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 mov dword ptr [ebp-4],ecx
00000007 cmp dword ptr ds:[003314B4h],0
0000000e je 00000015
00000010 call 61A639E3
00000015 mov eax,dword ptr [ebp-4]
00000018 mov eax,dword ptr [eax+4]
0000001b mov esp,ebp
0000001d pop ebp
0000001e ret
Run Code Online (Sandbox Code Playgroud)
如果你想要一种廉价的方式来投射'没有正确的类型检查',那么as运营商就是你的解决方案.
我打算给你那个你不想要的讲座,因为你显然不明白.
"测量,测量,测量!"有两个原因!(或等效地"Profile,Profile,Profile!")优化方法:
把努力放在最有影响力的地方.这就是术语"过早优化"的用武之地.
有时这个原因不适用(当你想知道理论/出于学术原因).
找出哪个实现更快.
现代CPU是复杂的野兽,甚至比较两个不同的机器代码序列也无法显示哪个更好,这是由于缓存行为的复杂性,管道数据依赖性,微代码等等.而且你运行的两个级别更高比那(C#代码 - > MSIL - >机器代码).如果不进行测量,将无法确定优化程度.
你说:
这会绕过编译时错误,但我不想这样做会导致性能下降:
Run Code Online (Sandbox Code Playgroud)output = (TOriginal)(object)oTemp;
但我认为那里确实没有任何表现.对于每种值类型,通用方法都是JITted,该过程应该完全消除任何想象的性能损失.但是,欢迎您通过性能数据(实际分析器测量)或至少反汇编JIT生成的机器代码来证明实际存在成本.
在这种特殊情况下,如果它们始终与您声明的类型相同,则不清楚为什么要开始使用两个不同的泛型类型参数.只是摆脱TOriginal并使用T输出参数的类型.
| 归档时间: |
|
| 查看次数: |
285 次 |
| 最近记录: |