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

简介:

互操作系列文章:

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

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

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

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

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

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

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

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

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

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

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

非托管代码:

 
  1. extern "C" _declspec(dllexportint _stdcall addA(int x,int y)  
  2. {  
  3.  return x+y;  

 托管代码申明1:

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

 托管代码申明2:

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

上面两段托管代码申明有些细微的不同的,第一个托管代码是我们常见的申明方式,而第二个是我们少见的申明,两种不同的申明方式对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位整型;

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


 本文转自 王清培 51CTO博客,原文链接:http://blog.51cto.com/wangqingpei557/601796,如需转载请自行联系原作者


相关文章
|
9天前
|
算法 Java 测试技术
使用 BenchmarkDotNet 对 .NET 代码进行性能基准测试
使用 BenchmarkDotNet 对 .NET 代码进行性能基准测试
40 13
|
7天前
|
Linux API C#
基于 .NET 开发的多功能流媒体管理控制平台
基于 .NET 开发的多功能流媒体管理控制平台
|
30天前
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
87 13
|
5月前
|
SQL 缓存 开发框架
分享一个 .NET EF6 应用二级缓存提高性能的方法
分享一个 .NET EF6 应用二级缓存提高性能的方法
|
2月前
|
开发框架 安全 .NET
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱
在数字化时代,.NET 技术凭借跨平台兼容性、丰富的开发工具和框架、高效的性能及强大的安全稳定性,成为软件开发的重要支柱。它不仅加速了应用开发进程,提升了开发质量和可靠性,还促进了创新和业务发展,培养了专业人才和技术社区,为软件开发和数字化转型做出了重要贡献。
35 5
|
2月前
|
传感器 人工智能 供应链
.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。
本文深入探讨了.NET开发技术在数字化时代的创新作用,从高效的开发环境、强大的性能表现、丰富的库和框架资源等方面揭示了其关键优势。通过企业级应用、Web应用及移动应用的创新案例,展示了.NET在各领域的广泛应用和巨大潜力。展望未来,.NET将与新兴技术深度融合,拓展跨平台开发,推动云原生应用发展,持续创新。
46 4
|
2月前
|
机器学习/深度学习 人工智能 Cloud Native
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台
在数字化时代,.NET 技术凭借其跨平台兼容性、丰富的类库和工具集以及卓越的性能与效率,成为软件开发的重要平台。本文深入解析 .NET 的核心优势,探讨其在企业级应用、Web 开发及移动应用等领域的应用案例,并展望未来在人工智能、云原生等方面的发展趋势。
45 3
|
2月前
|
开发框架 安全 Java
.NET技术的独特魅力与优势,涵盖高效的开发体验、强大的性能表现、高度的可扩展性及丰富的生态系统等方面,展示了其在软件开发领域的核心竞争力
本文深入探讨了.NET技术的独特魅力与优势,涵盖高效的开发体验、强大的性能表现、高度的可扩展性及丰富的生态系统等方面,展示了其在软件开发领域的核心竞争力。.NET不仅支持跨平台开发,具备出色的安全性和稳定性,还能与多种技术无缝集成,为企业级应用提供全面支持。
37 3
|
2月前
|
人工智能 Java 编译器
.NET 9 发布 性能提升、AI 支持与全方位改进
【11月更文挑战第5天】.NET 9 引入了多项改进,包括性能提升、AI 支持和全方位功能优化。性能方面,编译器增强、服务器 GC 优化、矢量化和硬件支持等提升了执行效率。AI 方面,新增学习材料、合作伙伴生态、原生支持和生成式 AI 集成。此外,.NET Aspire 组件升级、编程语言新功能和开发工具更新进一步提升了开发体验。
|
2月前
|
存储 设计模式 编解码
.NET 8.0 通用管理平台,支持模块化、WinForms 和 WPF
【11月更文挑战第5天】本文分析了.NET 8.0 通用管理平台在模块化、WinForms 和 WPF 方面的优势。模块化设计提升了系统的可维护性和可扩展性,提高了代码复用性;WinForms 提供了丰富的控件库和简单易用的开发模式,技术成熟稳定;WPF 支持强大的数据绑定和 MVVM 模式,具备丰富的图形和动画功能,以及灵活的布局系统。