Switch底层执行原理

switch底层执行原理     

   switch语句根据一个整数索引值进行多重分支,底层采用跳转表这种数据结构。跳转表是一个数组,表项i对应代码段的地址,当switch索引值等于表项i时采取对应的程序操作。

简单可理解为:执行switch时生成一个长度为最大case常量+1的数组,程序首先判断switch变量是否大于最大case 常量,若大于,则跳到default分支处理;否则取得数组索引号为switch变量值大小,取得数组对应值即为相应case代码块地址,程序接着跳到此地址执行,完成分支的跳转。


但实际计算机底层实现这一操作会更加复杂一点,以下参考《深入理解操作机系统》

   图a是一个简单的switch例子,对于case值有100、102~104、106;case值102 与 104 是没有break语句结尾。

   图b是使用C语言的扩展形式来描述的,每个表项都是一个代码块的地址(指针),这里的“&&”指的就是“&”。

    1. 执行switch时,会生成一张跳转表,表项数为(最大case值-最小case值+1),跳转表是一个数组,数组是一段连续的内存,jt数组中包含了7个表项(数组索引对应值),每个都是指向对应代码块的指针。
    2. 编译器将switch值n-最小case值(100),把取值范围移动到0至6之间,创建出一个新的程序变量index。首先判断index是否大于6,来判断是否在范围之外,如果超出直接执行default,即log_def指针对应代码块。
    3. 否则,根据索引的值直接跳转不同位置。                  

                               Switch底层执行原理_第1张图片                      Switch底层执行原理_第2张图片

   执行if-else是逐个条件进行判断,直到命中;与if-else语句相比,使用跳转表的优点是执行switch语句的时间与数量无关,且读取switch参数时只读取一次,就可跳到对应分支;缺点是维系了一个连续的数组,实际时使用空间换时间。

   补充:正因为要将case值转换为表项i,以及switch值要根据case值转换为对应数组索引,所以switch入参时是不支持byte、float、double型,以及对应case分支也是不支持byte、float、double型的。


关于switch与if-else的简单优化

     暂且不说if-else与switch相比哪一个的执行效率高,先就知道原理后,我们应如何去优化。

if-else

     对于if-else,在系统是自上而下逐个条件去判断,直到命中;所以应将机率大的条件置于最前面。以下给出一个简单例子

double random  = Math.random()*100;//生成0-100的随机数
		if(random > 10){ //90%
			
		}else if(random > 5){//5%
			
		}else{//剩下的5%
			
		} 

     对于条件机率相等或是条件个数非常多的情况,因为switch的执行时间与条件数量无关,他是根据switch值直接跳转到对应分支,所以可以选择switch代替if-else。

switch

     对于switch,实际上是根据case最小值与最大值,维系了一段连续的内存空间,以空间换取时间。以下给出一个简单的反例,最大值与最小值跨度较大,且之间没有更多的条件情况,那个无疑实际申请的很多空间是没用的,所以就应考虑使用if-else在代替。

int random = (int) Math.random() * 100;// 生成0-100的随机数
		switch (random) {
		case 0:
			break;
		case 100:
			break;
		}


《深入操作机系统》下载链接:http://download.csdn.net/download/abrazen_zz/9706844

你可能感兴趣的:(Java开发,计算机原理)