复习笔记10 switch 编译器优化的两种方式 和if的效率对比


public class Test11
{
	public static void main(String[] args)
	{
		//输出的是0和1,看起来没有问题,不过要是
		//0的时候输出a,1的时候输出b呢?
		for(int i = 0; i < 3; i++)
		{
			//根据i的值进行选择输出
			switch(i)
			{
				case 0:
				case 1:
					System.out.println(i);
			}
		}
		System.out.println("=====================================>");
		
		//输出的是abb,这就不对了,switch语句是
		//从上到下执行,并在满足条件的case处,执行
		//到switch结束的大括号里所有的语句,并
		//不在进行case匹配
		for(int i = 0; i < 3; i++)
		{
			//根据i的值进行选择输出
			switch(i)
			{
				//当i=0时执行输出a
				case 0:
					System.out.println("a");
				//当i=0和当i等于1时都执行输出b
				case 1:
					System.out.println("b");
			}
		}
		System.out.println("=====================================>");
		
		//上边的问题产生可以通过break语句达到目的
		for(int i = 0; i < 3; i++)
		{
			//根据i的值进行选择输出
			switch(i)
			{
				//当i=0时执行输出a并中断switch
				case 0:
					System.out.println("a");
					break;
				//当i=1时执行输出b,这里由于是
				//switch结尾可以不加break;但
				//还是建议加上
				case 1:
					System.out.println("b");
					break;
			}
		}
		System.out.println("=====================================>");
		
		//不满足case条件的语句可以通过default匹配
		//但default并非真正好用,他会先进行全部的
		//case,最后才会进default,这很影响效率
		for(int i = 0; i < 3; i++)
		{
			//根据i的值进行选择输出
			switch(i)
			{
				//当i=0时执行输出a并中断switch
				case 0:
					System.out.println("a");
					break;
				//当i=1时执行输出b,这里由于是
				//switch结尾可以不加break;但
				//还是建议加上
				case 1:
					System.out.println("b");
					break;
				default:
					System.out.println("nono");
					break;
			}
		}
		System.out.println("=====================================>");
		
		//什么情况下应该用switch?一般在不超过15个左右的
		//case的情况下需要对值进行判断才会用switch
		
		//switch的另外一种使用情况,也叫做if优化,
		//这样的if,每次表达式判断都会取x的值,而
		//如果换成switch则只会取一次值,效率略高
		int x = 0;
		if(x == 3);
		if(x == 0);
		if(x == 2);
		
		//switch本身也具备编译器优化方案,比如值比较密集
		//的情况
		//编译器对于这种会创建一个tableswitch的表,并进行
		//如下操作
		//1.创建0-6的表并关联行号,想成一个map就行,i是key
		//  case 后的代码所在行数是value
		//2.不在取值范围内的则直接default
		//3.在取值范围内,进行i-0,不一定是0,这里的0是指
		//  case范围的最小值,以这个i-0的值直接访问这个类似
		//  的map,进行直接跳转,所以并不是逐一比较的
		for (int i = 0; i < 10; i++)
        {
	        switch(i)
	        {
	        	case 2: x=5/3; break;
	        	case 1: x=5/3; break;
	        	case 11: x=5/3; break;
	        	default: x=5/3; break;
	        	case 8: x=5/3; break;
	        	case 5: x=5/3; break;
	        }
        }
		System.out.println("=====================================>");
		
		//第二种就是正常的switch,编译器同样会生成表,但跟上边
		//的连续表不一样的,而是仅保存了与case相关的lookupswitch
		//他的执行方式是逐一匹配,都没成功则default。
		//而代码中的800,看似是想先匹配800,实际上是错误的,因为
		//编译器做的这个表,是由小到大的顺序
		for (int i = 0; i < 10; i++)
        {
	        switch(i)
	        {
	        	case 200: x=5/3; break;
	        	case 100: x=5/3; break;
	        	case 1100: x=5/3; break;
	        	default: x=5/3; break;
	        	case 800: x=5/3; break;
	        	case 500: x=5/3; break;
	        }
        }
		System.out.println("=====================================>");
		
		//根据上边的case代码,假设我们预先知道800的出现几率最高
		//假设为99%,那么上边的第二种switch就会耗费大量时间进行
		//匹配,虽说会取值会比if少取,但真的比if快?
		if(x == 800);
		if(x == 600);
		//如果我们的if是这样写的话,判断次数要比switch少太多了,
		//而对于case条件多的情况下,快的更多,那么在这种情况下,
		//switch的取值优势将会荡然无存
		for (int i = 0; i < 10; i++)
        {
			if (i == 200) x=5/3;
			else if (i == 100) x=5/3;
			else if (i == 1100) x=5/3;
			else if (i == 800) x=5/3;
			else if (i == 500) x=5/3;
        	else x=5/3;
        	
        }
		System.out.println("=====================================>");
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值