.NET简谈互操作(六:基础知识之提升平台调用性能)

简介: 互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之Dispose非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习。

互操作系列文章:

  1. .NET简谈互操作(一:开篇介绍)

  2. .NET简谈互操作(二:先睹为快)

  3. .NET简谈互操作(三:基础知识之DllImport特性)

  4. .NET简谈互操作(四:基础知识之Dispose非托管内存)

  5. .NET简谈互操作(五:基础知识之Dynamic平台调用)

  6. .NET简谈互操作(六:基础知识之提升平台调用性能)

  7. .NET简谈互操作(七:数据封送之介绍)

我们继续.NET互操作学习。本篇文章我们将来学习互操作基础知识中的最后一个知识点“提升平台调用的性能”;

在于非托管函数进行互操作的过程中,由于涉及的技术因数众多,因此程序的性能会受到这些因素的影响导致性能下降,本篇文章将来介绍在平台调用过程中提升性能的一些设计和编码方面的技巧;[王清培版权所有,转载请给出署名]

一:显示的制定要调用的非托管函数名称

我们在进行平台调用的时候,如果CLR无法在非托管DLL中找到与DllImport特性指定的函数名相同的非托管函数,那么CLR会尝试采用一些规则重新进行搜索。比如我们将sumA非托管函数的CharSet申明为CharSet.Ansi,那么CLR首先会通过根函数名(sum)进行搜索,如果在指定的非托管DLL中找到了此函数,就是用它。如果不能找到,就会使用带后缀A的函数(sumA)进行搜索。其实为什么会出现这种情况,原因来自于字符编码的不同,有的函数实现是采用Ansi方式,有的采用Unicode方式,这两种编码方式的不同最终导致数据在内存的存放也不同,所以在进行非托管调用的时候,我们需要注意;

非托管代码:

extern "C" _declspec(dllexport) int _stdcall addA(int x,int y)
{
 return x+y;
}

托管代码申明1:

[DllImport("Win32DLL.dll",EntryPoint = "add", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int add(int x, int y);

托管代码申明2:

[DllImport("Win32DLL.dll",EntryPoint = "addA", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall,ExactSpelling=true)]
public static extern int add(int x, int y);

上面两段托管代码申明有些细微的不同的,第一个托管代码是我们常见的申明方式,而第二个是我们少见的申明,两种不同的申明方式对CLR的平台调用来说是不一样的,相对而言的调用过程也有少许的不同,经测试第二种的申明能提升少许的性能;第二种的代码申明中出现了ExactSpelling=true(显式的指定要调用的非托管函数的名称),这段代码的意思是说,我们强制使用EntryPoint申明的方法入口点,不允许CLR帮我们去动态的调整函数的名称在去查找入口名称,这样能省掉了CLR的查找时间;

二:对数据封送处理进行优化

在托管代码与非托管代码之间传递参数时,无论是传入还是传出,都要经过封送拆收器的封送处理。由于封送过程可能会涉及数据类型的转换,以及在非托管内存与非托管内存之间来回复制数据,所以封送处理也是影响平台调用性能的瓶颈之一。

CLR在进行数据封送时,只有两种选择的方式:要么锁定数据、要么复制数据。在默认的情况下CLR会在封送过程中复制数据,假如我们需要将一个Unicode字符串作为Ansi传递到非托管代码中时,首先CLR会将字符串复制一份出来,然后将复制出来的字符串进行转换成Ansi,然后在将转换后的Ansi字符串的内存地址传递给非托管代码;由于复制数据操作可能很浪费时间,所以封送数据也是影响性能的瓶颈之一;

数据封送还有一种就是锁定内存的方式,意思就是说CLR可以通过直接将托管对象锁定在垃圾回收堆上,已防止托管对象在函数调用生命周期内被回收,一旦托管对象被锁定,就可以直接将指向托管对象的指针传递给非托管代码中,这样就避免了复制数据的操作,达到优化的目的;

但是不是所有的数据类型都能被锁定的,要想能被锁定,必须具备一些跟平台相关的约定,我们来看要满足那些条件的对象才能被CLR锁定;

1.必须是托管代码调用非托管代码,也就是本机代码;

2.托管数据类型必须是可直接复制到本机结构(blittable)中的数据类型,或者能够在满足某些条件下转换成本机结构数据类型;

3.传递的不是引用(ref,out)参数;

4.被调用代码和调用代码必须处于同一线程上下文或者线程单元中;

经过我们上面的总结,我们就可以发现,要想减少封送拆收器的数据复制操作,我们可以用本机结构类型进行传递,所谓本机结构类型就是在托管内存中和非托管内存中的表示形式是完全一样的。[王清培版权所有,转载请给出署名]

所以在准备开发平台调用程序时,我们尽量的考虑使用本机数据结构;如:System.Byte:无符号8位整型、System.SByte:有符号8位整型;

总结:由于这篇文章涉及到了数据封送的相关技术,很快我们结束了基础部分的学习,下面我们将进入学习互操作数据封送相关技术;

目录
相关文章
|
6月前
|
SQL 数据库 开发工具
“.NET视频总结:认识框架的结构和组件,掌握开发工具的奥妙“
“.NET视频总结:认识框架的结构和组件,掌握开发工具的奥妙“
81 0
|
算法 程序员 Linux
MKL.NET:为.NET开发者提供高性能数学计算支持的开源库
MKL.NET:为.NET开发者提供高性能数学计算支持的开源库
128 0
|
JavaScript 前端开发 Java
一起谈.NET技术,.NET平台上的JavaScript引擎
  长久以来,在.NET平台上只能通过JScript.NET执行ECMAScript/JavaScript代码,但是该项目一直是.NET语言中的二等公民,甚至Mono中的对应项目也已经无人维护。不过在JScript.NET逐渐淡出人们视线的时候,.NET平台上也出现了一些新的JavaScript执行引擎,虽不完善,但值得关注。
1342 0
|
监控 算法 前端开发
一起谈.NET技术,Silverlight 的多线程能力(下)
  上一期笔者介绍了Silverlight实现多线程的诸多解决方案,本期笔者将通过一个实例来实现所有多线程编程方法,并且还将于JavaScript和Flash两种Web客户端技术性能进行比较,请勿拍砖。
890 0
|
监控 JavaScript 算法
Silverlight 的多线程能力(下“.NET技术”)
  上一期笔者介绍了Silverlight实现多线程的诸多解决方案,本期笔者将通过一个实例来实现所有多线程编程方法,并且还将于JavaScript和Flash两种Web客户端技术性能进行比较,请勿拍砖。
963 0
一起谈.NET技术,.NET并行(多核)编程系列之七 共享数据问题和解决概述
  之前的文章介绍了了并行编程的一些基础的知识,从本篇开始,将会讲述并行编程中实际遇到一些问题,接下来的几篇将会讲述数据共享问题。   本篇的议题如下:   1.数据竞争   2.解决方案提出   3.
920 0
|
Web App开发 SQL 关系型数据库
一起谈.NET技术,Silverlight与PostgreSQL数据库的互操作(CURD完全解析)
  今天将为大家介绍如何让Silverlight使用PostgreSQL作为后台数据库以及CURD操作。   准备工作    1)建立起测试项目    细节详情请见强大的DataGrid组件[2]_数据交互之ADO.NET Entity Framework——Silverlight学习笔记[10]。
1010 0
|
Java 关系型数据库 程序员
一起谈.NET技术,分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发
  在许多年前,“语言”就等同于“平台”,例如C,C++以及最早的Ruby和Python等等。但是随着技术发展,出现了一些通用的平台,例如.NET和Java,逐渐这些平台上的语言也越来越多。再后来,某些语言在不同平台上的实现也越来越多,事情也变得有些复杂。
1542 0
|
Web App开发 缓存 .NET
【推荐】【给中高级开发者】构建高性能ASP.NET应用的几点建议
本篇目录 早期阶段就要对应用进行负载测试 使用高性能类库 你的应用是CPU密集还是IO密集的 使用基于Task的异步模型,但要慎重 分发缓存和会话(session)状态 创建Web Gardens 巧妙地使用缓存和懒加载 不要在MVC视图中放C#代码 适当时使用Fire & Forget 为x64 CPU创建 使用服务器上的监视和诊断工具 分析运行中的应用 如果你在构建一个面向公众的web站点,那么在项目结尾时你想要实现的就是web负载性能良好。
1452 0
下一篇
无影云桌面