C#性能理解以及CTS

简介:

关于C#/.NET性能

在上次的例子里面,第二次执行Console.WriteLine()方法时,会完全跳过JITCompiler编译。因为第一次已经完全编译为了本地CPU指令并且返回了指令在内容里的入口地址,所以这一次会直接跳转到该方法的内存地址处执行代码,当然也会比第一次的性能要高。

C#性能较之C/C++低在哪?

在托管环境中,完成代码的编译会经历两个过程:

1.源码首先被编译为IL代码

2.执行代码时,IL会经历第二次编译为本地CPU指令,这个过程需要分配更多的内存和占用CPU资源。

怎么客观地看待这个部分?

1.首先必须承认二次编译的确损害了性能,并且分配了动态内存。分配动态内存意味着当程序终止时,编译的代码会被丢弃。再次运行程序或启动两个程序的实例,JIT编译器会再次将IL编译为本地CPU指令。非托管语言(C/C++)编译器会针对具体的CPU平台编译,调用时直接执行。

2.对大多数程序而言,都会反复多次调用同一个方法。这些方法仅仅在第一次被调用时会进行二次编译,从而降低了性能。其实,可能有时在一个方法里面执行的时间比调用一个方法的时间长的多,所以即使是第一次调用需要消耗性能,可能相对于在整个方法执行的时间来说只是占用了一小部分比例。

3.微软做了很多优化的工作来保证将性能的损耗降到最低。例如,在IL编译为本地CPU指令时,编译器能够比非托管编译器知道更多关于执行环境的信息。下面列举托管编译器胜过非托管编译器的几个方面:

①JIT编译器能够判定程序是否运行在Intel Pentium 4 CPU上,并且利用Pentium 4CPU提供的任何专用的指令的优势来生成本地CPU指令。通常,非托管程序会针对最普遍CPU情况编译,从而避免使用CPU提供的专用指令来提升性能。

②JIT编译器能够确定当一个测试在机器上运行时始终为false的情形。例如:if(numberOfCPUs>1){...}.如果宿主机器只有一个CPU,那么这段代码能够让JIT编译器不生成任何CPU指令。这种情形能够让本地CPU指令得到一些微调,从而让代码更小执行更快。

认识IL

IL是基于栈的,所有IL指令通过push操作到执行栈,并且通过pop操作将结果出栈。由于IL没有提供操作寄存器的指令,很容易让人们创造出针对CLR的语言和编译器。IL指令也是无类型的。例如,IL提供的Add指令(将最后两个操作push到栈)并没有两个针对32位和64位的Add指令。当Add指令执行时,它会决定栈上操作的类型并执行适合的操作。

IL的优点

1.从底层的CPU抽象出来

2.健壮性和安全性:IL编译为本地CPU指令时,CLR执行了一个审核过程,检查高级IL代码确保它们是安全的,例如方法被调用时,参数的个数和类型是否正确;如果有返回值,那么检查方法是否有return语句等等。托管模块的元数据包含了审核过程需要的所有方法和类型信息。在Windows中,每一个进程有它自己的虚拟地址空间,这很有必要,因为你不能信任一个程序的代码。程序完全有可能从一个未验证的内存地址读取或写入,放到独立的地址空间增强了程序的健壮性和稳定性。而且这样可以在一个Windows虚拟地址空间运行多个托管程序。

3.由于进程会占用Windows的资源,进程越多占用的越多。多个托管程序可以运行在一个操作系统进程从而提升了性能。

CLR怎么实现在一个进程运行多个托管程序?

每一个托管程序在一个应用程序域执行。默认情况下,每一个托管的exe文件运行具有一个应用程序域的独立地址空间,CLR的宿主进程能够运行多个应用程序域。

了解不安全代码

微软C#编译器默认生成的是安全代码——代码是经过安全审核的。C#编译器也允许开发这写不安全的代码——直接操作内存地址以及在内存中的字节。这个功能在我们与非托管代码交互时非常有用。所有方法在包含不安全代码时,必须标记unsafe。当JIT编译器试图编译一段不安全代码时,它会检查该代码是否通过设置System.Security.Permissions.SecurityPermissionFlag’s SkipVerification标志授权。如果设置了该标志位,CLR会信任该段代码并期望直接地址和字节操作不会引起任何损害。如果没有设置会抛异常。

认识公共类型系统CTS

1.CTS:描述类型的定义及行为。

2.CTS规范声明了一个类型能够包含0个或多个成员:字段,方法,属性,事件。

3.CTS也规定类型及其成员的可访问性,下面列举出来:

Private:同一个类里面可以访问

Family:能够被派生类里面的成员访问,而不用考虑是否在同一个程序集里里面。C#里面用Protected修饰

Family and assembly:能够被在同一个程序集里面的派生类成员访问。C#及VB没有提供该访问控制修饰,IL汇编语言是可以的。

Assembly:同一个程序集可以访问。C#里面用internal修饰

Family or assembly:能够被派生类访问(不管是否在同一个程序集),也能够被同一个程序集的任何类型访问(不用考虑是否是派生类)。C#用protected internal修饰

public:没有限制。

4.CTS定义了类型继承的规则,虚方法,对象生命周期等等。

5.CTS规定所有类型必须从System.Object继承。Object是定义在System命名空间下的,是所有类型的根,这样可以保证所有的类型具有一个最小化的行为集合。System.Object定义下面几种行为:①两个实例的比较   ②获取实例的哈希代码   ③查询实例的真实类型   ④执行类型的浅复制  ⑤获取实例对象当前状态的字符串表示

注   《CLR via C#》(Jeffrey Richter著)——.NET 界的经典之作,读的过程写点笔记跟大家分享,我也推荐大家看英文版,能够直接领会原意 

本文转自Rt-张雪飞博客园博客,原文链接http://www.cnblogs.com/mszhangxuefei/archive/2012/07/10/clrnotes-2.html如需转载请自行联系原作者


张雪飞

相关文章
|
7月前
|
编译器 C# 开发者
C# 10.0中插值字符串的改进:灵活性与性能的双重提升
【1月更文挑战第19天】C# 10.0带来了对插值字符串的显著改进,进一步增强了这一功能的灵活性和性能。插值字符串是C#中处理字符串格式化的一种强大方式,它允许开发者直接在字符串中嵌入变量和表达式。在C# 10.0中,插值字符串不仅获得了语法上的简化,还通过新的编译时优化提高了运行时性能。本文将详细探讨C# 10.0中插值字符串的改进内容,以及这些改进如何为开发者带来更加高效和便捷的编程体验。
|
14天前
|
缓存 API C#
C# 一分钟浅谈:GraphQL 优化与性能提升
本文介绍了 GraphQL API 的常见性能问题及优化方法,包括解决 N+1 查询问题、避免过度取数据、合理使用缓存及优化解析器性能,提供了 C# 实现示例。
63 33
|
16天前
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
61 13
|
4月前
|
开发者 C# Android开发
Xamarin 与 .NET:解锁现代化移动应用开发的超级武器——深入探讨C#与.NET框架如何赋能跨平台应用,实现高效编码与卓越性能
【8月更文挑战第31天】Xamarin 与 .NET 的结合为开发者提供了强大的平台,用于构建现代化移动应用。通过 C# 和 .NET 框架,Xamarin 可以实现一次编写、多平台运行,覆盖 iOS、Android 和 Windows。这种方式不仅节省了开发时间和成本,还保证了应用的一致性和高质量。Xamarin 是一个开源框架,专为跨平台移动应用开发设计,允许使用 C# 语言和 .NET 核心库构建原生应用,并访问各平台特定功能。微软维护的 Xamarin 是 Visual Studio 生态系统的一部分,极大地提高了开发效率。
93 0
|
7月前
|
缓存 算法 测试技术
优化 C#编程性能的策略
【4月更文挑战第20天】优化C#性能策略包括:选择合适算法和数据结构,避免频繁对象创建,缓存常用数据,减少内存分配,使用异步编程,优化数据库操作(如合理查询和使用索引),利用多线程并行处理,精简代码,使用性能分析工具,硬件升级,以及进行性能测试。综合应用这些策略可提升程序性能和响应性。
73 4
|
开发框架 Rust .NET
TechEmpower 21 轮 Web 框架性能评测 -- C# 的性能和 Rust、C++ 并驾齐驱
版权声明:本文为 CSDN 博主「shanyou」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/shanyou/article/details/126081288
1695 1
|
C# C++ 索引
30天C#基础巩固------this,base,string中的方法,StringBuilder性能
30天C#基础巩固------this,base,string中的方法,StringBuilder性能
164 0
30天C#基础巩固------this,base,string中的方法,StringBuilder性能
浅析C#/Java程序中字符串操作的性能问题。
在C#等面向对象语言中,虽然String是引用类型,但和普通的引用类型相关还是有较大的特殊型的。主要体现在两点: string中只有两个只读的属性,没有可设置的属性,所以说string 类型的实例具有固定不变性。
666 0