关于P/Invoke平台调用的性能优化研究 之一

在程序设计中我秉承的优化策略是只要性能提升有帮助,哪怕只能提千分之一毫秒的时间的方法都值得采用。

平台调用是一个损耗性能的方式,比如.Net里已经提供了Console.WriteLine,你也可以通过平台调用使用非托管代码的Printf,但这种无意义的平台调用只会让封送拆封其无意义的执行损耗程序的性能。

所以我给出的第一条建议是:1.只在必要的时刻进行平台调用,否则推荐使用托管代码。 

如果必须进行平台调用,那么你应该继续看下去,如果不是必要的可以看到这就结束了 :)

2.显示的制定要调用的非托管函数的名称

我们首先来看下CLR进行平台调用时是如何所有想匹配的函数名称的,如果进行平台调用时指定了CharSet=CharSet.Ansi 那么CLR首先在非托管的DLL中寻找,如果找不到,就是用带A后缀的函数进行搜索,这种搜索的方式会给性能带来一定的影响,所以一旦我们知道要调用的具体的函数名称那么就应该将ExactSpelling的值设为true防止CLR通过修改入口名称进行搜索

例如如下的两个平台调用代码

非托管函数原型

void __cdecl MessageA(char* AStr,char* BStr )

 

平台调用代码

[DllImport("Native.dll",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.Cdecl)]

 public static extern void Message(string Astring,string BString);

 

[DllImport("Native.dll",CharSet = CharSet.Ansi,CallingConvention = CallingConvention.Cdecl,ExactSpelling = true)]

public static extern void MessageA(string AString,string BString );

对于第一种封装来说 由于Native.dll中并不存在Message这个函数名,所以CLR首次寻找会失败,然后继续寻找MessageA才成功。

而对于第二种封装来说,CLR会直接去寻找MesssageA这个入口并一次成功,实验证明这大约可以节约千分之三毫秒的时间。但任何的性能提升都是值得做的。

 

 

 

posted @ 2010-09-01 15:47  李崇森  阅读(856)  评论(0编辑  收藏  举报