在调用Win32/COM方法时,通常会有明显的性能损失吗?

30

我想知道是否有人对使用DLLImport/PInvoke从托管的.Net代码调用Win32方法的负面影响有一个合理的解释或概述?

我计划使用各种Win32方法,并希望更加深入地了解这样做的负面影响。

谢谢,

Brian。

2个回答

37
根据MSDN - 从托管代码调用本机函数
PInvoke每次调用的开销在10到30个x86指令之间。除了这个固定开销外,封送会产生额外的开销。在托管代码和非托管代码中具有相同表示的可平面化类型之间没有封送成本。例如,int和Int32之间的转换没有成本。
根据我的经验,在P/Invoke本机函数时确实存在开销,但通常性能影响不值得担心。封送成本是需要记住的事情。如果传入大型结构、字符串等,则性能成本将很快显示出来。
对于频繁调用的P/Invoked函数,您可能希望考虑将[SuppressUnmanagedCodeSecurity]添加到P/Invoke函数定义中(请参见MSDN-SuppressUnmanagedCodeSecurityAttribute)。这可以防止运行时进行堆栈遍历以确保调用者具有UnmanagedCode权限。当然,在添加此属性之前,请确保您理解安全性方面的影响。

5
.NET Core移除了CLR中的“部分信任”功能,因此[SuppressUnmanagedCodeSecurity]不再需要(事实上,它已从.NET Core中完全删除):https://github.com/dotnet/runtime/issues/4514 - Dai
创建一个C++/CLI包装库来调用本地函数,这样会有所帮助吗? - nikeee

4

以下是我对PInvoke的一些问题的看法:

  • 参数驱动可以很昂贵,具体取决于数据类型(可平铺/不可平铺)
  • 正确的参数驱动通常不是非常直观的
  • PInvoke不提供任何编译时安全性。一个人很容易错拼DLL或函数名称而不会受到编译器的投诉。

如果您计划使用大量未托管的函数,我建议创建混合DLL(本机和托管混合程序集),而不是声明一堆PInvokes。


谢谢您的反馈。我希望能得到一些费用方面的例子。这是您之前发现过的吗? - Brian Scott
抱歉 Brian,那些只是我的 PInvoke 主观经验。我无法提供任何具体的基准。请查看 http://msdn.microsoft.com/en-us/library/ky8kkddw.aspx - Florian Greinacher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接