zhouqijie

提高平台调用性能



提高平台调用性能的一些方式

为了提升性能,最佳的做法是一旦确定了要调用的函数,最好将ExactSpelling字段设置为true以阻止CLR通过修改入口点名称来搜索函数。

CLR在数据封送时,有两种选择,一是锁定(pin)对象,阻止托管对象在函数调用期间被移动或者回收。二是对数据进行复制。复制的操作比较费时,是影响平台调用性能的因素之一。

锁定托管对象需要满足的条件:

  1. 必须是托管代码调用本机代码。
  2. 托管数据类型必须是Blittable类型或者能转变成Blittable类型的数据类型。
  3. 传递的不是引用参数(ref或out)。
  4. 被调代码和调用代码必须在同一线程上下文或者线程单元。

如果可能的话,尽量不要逐次对非托管函数进行平台调用。如果平台调用结果只是中间结果,则可以将所有的计算过程放到非托管函数中。

字符集的转换必然会牺牲性能,复制字符串到非托管内存时,也是会耗费时间的,从而带来性能损失。



关于Blittable类型

Blittable类型是指对于托管代码和非托管代码而言,其在内存中的表示形式完全一样的数据类型。

Blittable数据类型:
|数据类型|描述| |-|-| |System.Byte|无符号8位整型| |System.SByte|有符号8位整型| |System.Int16|…| |System.UInt16|…| |System.Int32|…| |System.UInt32|…| |System.Int64|…| |System.UInt64|…| |System.Single|…| |System.Double|…| |System.IntPtr|平台相关的有符号指针类型| |System.UIntPtr|平台相关的无符号指针类型|

Non-Blittable数据类型:
|数据类型|描述| |-|-| |System.Array|转换为C风格的数组或者SAFEARRAY| |System.Boolean|转换为1字节、2字节或4字节的整数值| |System.Char|转换为Unicode或者ANSI| |System.Class|转换成类接口| |System.Object|转换成变量或者接口| |System.Mdarray|转换为C风格的数组或者SAFEARRAY| |System.String|转换成’/0’结束的C风格字符串或者BSTR| |System.ValueType|转换成固定内存布局的结构体| |System.Szarray|转换为C风格的数组或者SAFEARRAY|

其他Blittable数据类型:
|数据类型|描述| |-|-| |Blittable[]|元素是Blittable类型的一维数组| |blittable struct|成员数据类型都是Blittable类型的格式化值类型|

其他的可变成Blittable类型的数据类型示例:
|数据类型|描述| |-|-| |char(Unicode)|(将CharSet显式指定为Unicode)| |MarshalAs(UnmanagedType.LPWSTR) char|或者单独为char类型加上MashalAs特性| |…|…|

(END)