C#与.NET程序员面试宝典 2.2.2 面试题9:如何使用实时编译进行代码优化

实时编译,也就是JIT,具有跨平台的优点,实时编译也保证了在新的硬件技术推出后,原先写的代码可以不需要重新编译就直接享用新的技术带来的优点。 但JIT本身作为一种技术,当然存在执行效率低、第一次启动时间长的缺点。

 

【出现频率】★★★★

 

【关键考点】

JIT的基本概念

JIT自动优化

 

【考题分析】

目前有两种方式可以产生本机的机器代码:实时编译(JIT)和预编译方式(产生Native Image)。JIT的全称是实时编译(Just-In-Time),程序员掌握JIT工作原理是很有必要的。当需要校调对性能要求很高的代码时,MSIL通常不是最好的做法,JIT优化器会默认地优化程序代码。使用过ildasm或Reflector工具的程序员会发现在Release和Debug模式下产生的MSIL代码几乎完全相同,但由于使用JIT优化,因此Release模式的代码运行效率会如此迅速。

 

笔者将通过Native Code(本地代码)来查找系统所做的优化,只有当要调用某个方法时,JIT编译器才会将MSIL的方法体编译为相应的本机机器码,这样做可以优化程序的工作集。首先看一段简单的测试代码:

 

namespace MyConsole

{

    class HelloKitty                                                                                      //定义一个简单类HelloKitty

    {

        static void Main(string[] args)                                                      //主程序

        { 

        Console.WriteLine("这是一个MSIL测试程序,Hello Kitty"); //输出一个测试信息     

        Console.Read();                                                                                    

        }

    }

}

 

下面看一下Debug模式下测试代码的本地代码,如下所示。

 

//将上面C#代码编译成MSIL代码

namespace MyConsole

{

    class HelloKitty                                                                                      //定义一个简单类HelloKitty

    {

        static void Main(string[] args)                                                      //主程序

        { 

00000000  push        ebp

00000001  mov         ebp,esp

00000003  push        edi 

00000004  push        esi 

00000005  push        ebx 

00000006  sub         esp,30h

00000009  xor         eax,eax

0000000b  mov         dword ptr [ebp-10h],eax

0000000e  xor         eax,eax

00000010  mov         dword ptr [ebp-1Ch],eax

00000013  mov         dword ptr [ebp-3Ch],ecx

00000016  cmp         dword ptr ds:[009892FCh],0

0000001d  je          00000024

0000001f  call        764F8F29

00000024  nop             

        Console.WriteLine("这是一个MSIL测试程序,Hello Kitty");  //输出一个测试信息        

00000025  mov         ecx,dword ptr ds:[022C2088h]

0000002b  call        75BC2280

00000030  nop             

        Console.Read();

00000031  call        75BC2D14

00000036  nop             

        }

00000037  nop             

00000038  lea         esp,[ebp-0Ch]

0000003b  pop         ebx 

0000003c  pop         esi 

0000003d  pop         edi 

0000003e  pop         ebp 

0000003f  ret             

 

 

以下是Release模式下的代码:

 

namespace MyConsole

{

    class HelloKitty                                                                                      //定义一个简单类HelloKitty

    {

        static void Main(string[] args)                                                      //主程序

        { 

        Console.WriteLine("这是一个MSIL测试程序,Hello Kitty"); //输出一个测试信息        

00000000  push        ebp 

00000001  mov         ebp,esp

00000003  push        eax 

00000004  mov         dword ptr [ebp-4],ecx

00000007  cmp         dword ptr ds:[009992FCh],0

0000000e  je          00000015

00000010  call        764E8F29

00000015  mov         ecx,dword ptr ds:[022D2088h]

0000001b  call        75BB2280

        Console.Read();

00000020  call        75BB2D14

00000025  nop             

        }

00000026  nop             

00000027  mov         esp,ebp

00000029  pop         ebp 

0000002a  ret         

    

注意:同一段测试代码生成的Release模式下只有25行,而Debug模式下却有37行。Release模式下比Debug模式下小很多,也简洁清晰很多。在实时编译的过程中,JIT引擎会查找一个包含该类型所有方法存根的数据结构,对于未编译成机器代码的方法,存根会包含一个调用JIT的简单命令,当该方法的实时编译结束后,存根的命令会被替换成一条简单的Jmp指令,使得代码跳转到该方法的机器代码位置。这样导致整个项目的大小进一步的得到了优化,更能高效的执行本地代码。

 

【答案】

JIT的全称是实时编译(Just-In-Time),描述一种操作的词组,该操作只有在必要时才执行,如实时编译或实时对象激活。运行时需要代码时,将Microsoft中间语言 (MSIL) 转换为机器码的编译。

转载于:https://www.cnblogs.com/mianshibaodian/archive/2010/10/19/1855328.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现。 答:public class MainClass { public static void Main() { Console.WriteLine(Foo(30)); } public static int Foo(int i) { if (i <= 0) return 0; else if(i > 0 && i <= 2) return 1; else return Foo(i -1) + Foo(i - 2); } } 2.C#中的委托是什么?事件是不是一种委托? 答 :委托可以把一个方法作为参数代入另一个方法。 委托可以理解为指向一个函数的引用。 是,是一种特殊的委托。 3.override与重载的区别 答 :overrider与重载的区别。重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要。 Overrider是进行基类中函数的重写。为了适应需要。 4.如果在一个B/S结构的系统中需要传递变量值,但是又不能使用Session、Cookie、Application,您有几种方法进行处理? 答 : this.Server.Transfer 5.请编程遍历页面上所有TextBox控件并给它赋值为string.Empty? 答: foreach (System.Windows.Forms.Control control in this.Controls) { if (control is System.Windows.Forms.TextBox) { System.Windows.Forms.TextBox tb = (System.Windows.Forms.TextBox)control ; tb.Text = String.Empty ; } } 6.请编程实现一个冒泡排序算法? 答: int [] array = new int[] {1,3,5,8,0,2,3,10,8,10}; int temp = 0 ; for (int i = 0 ; i < array.Length - 1 ; i++) { for (int j = i + 1 ; j < array.Length ; j++) { if (array[j] < array[i]) { temp = array[i] ; array[i] = array[j] ; array[j] = temp ; } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值