我正在考虑将我的C#项目中的一小部分代码移植到C / ASM以获得性能优势。 (这部分代码使用了许多按位操作,并且是使用本机代码可能存在实际性能提升的少数几个地方之一。)然后我计划通过P / Invoke简单地调用单独DLL中的本机函数。现在,将在托管代码和本机代码之间传递的唯一数据将是纯粹的原始类型(bool,int,long,1D数组等)。所以我的问题是:使用P / invoke只需要原始类型就会有任何显着的开销吗?我知道在使用更复杂的类型时会有一些基本的开销,因为它们需要编组(固定/复制),但在我的情况下它可能相对有效(与在本机DLL本身内调用代码相比) )?如果有人能为我澄清这个问题,解释性能优势/点击的程度以及它们背后的原因,我们将非常感激。完成整个任务的另一种方法也是受欢迎的,但由于C#缺乏对内联汇编/ CIL的支持,我不相信有一个。
答案 0 :(得分:5)
来自MSDN(http://msdn.microsoft.com/en-us/library/aa712982.aspx):
“PInvoke每次调用的开销在10到30 x86之间。除了这个固定成本之外,编组还会产生额外的开销。在托管和非托管代码中具有相同表示的blittable类型之间没有编组成本。例如,在int和Int32之间进行转换没有成本。“
所以,它相当便宜,但一如既往,你应该仔细衡量,以确保你从中受益,并牢记任何维护费用。顺便说一下,对于任何复杂的互操作,我建议使用P / Invoke上的C ++ / CLI(“托管”C ++),特别是如果你对C ++感到满意的话。
答案 1 :(得分:1)
我似乎记得听说每个P / Invoke调用至少有30个机器操作开销。但是忽略理论,分析你的选择并选择最快的。
答案 2 :(得分:1)
我个人会设置一个带有用C#和非托管C ++编写的简单表达式的测试工具,然后对应用进行概要分析,看看你正在使用哪种性能增量。
要考虑的其他因素是您将在应用程序中引入维护问题,特别是如果您有初级开发人员希望维护代码。确保您知道自己获得了什么,以及您在性能,代码清晰度和可维护性方面所失去的内容。
另外,JIT的C#代码在算术运算方面应该具有与C ++相同的性能。
答案 3 :(得分:0)
您可以使用最终用户计算机上的ngen
生成.NET程序集的已编译优化版本(作为安装过程的一部分)。
根据我的经验,正确格式化的C#(例如,在循环之外保持分配)将表现得非常好。
答案 4 :(得分:0)
此链接提供了一些见解:http://www.codeproject.com/Articles/253444/PInvoke-Performance
还要注意应用[SuppressUnmanagedCodeSecurity]属性时的性能差异。