一个Java字节码有趣的问题

今天在Debug一个Java程序时,遇到一个问题就是源代码和Java字节码反编译之后的代码不一样。

源代码如下:

public CharSequence apply(final Object context, final Options options) throws IOException {
	String policy = (String)options.hash("policy", "advanced");
	if (context == null || StringUtil.isEmpty(context.toString())) {
		return options.hash("default", "");
	}
	String value = context.toString();
	if (value.startsWith(CDATA_START) && value.endsWith(CDATA_END)) {
		return value;
	}
	
	return sanitize(value);
}

在字节码反编译之后,显示的代码如下:

public CharSequence apply(Object context, Options options) throws IOException {
	String policy = (String)options.hash("policy", "advanced");
	if (context != null && !StringUtil.isEmpty(context.toString())) {
		String value = context.toString();
		return value.startsWith("<![CDATA[") && value.endsWith("]]>") ? value : sanitize(value);
	} else {
		return (CharSequence)options.hash("default", "");
	}
}

源代码中使用 || 操作符的判断,在字节码反编译之后,居然变成了&&的判断。

难道是&&的操作更快一些吗? 于是,写了如下测试代码进行测试:

    public static boolean testIfStatement1(String value) {
        if (value == null || value.length() == 0){
            return true;
        } else {
            return false;
        }

    }

    public static boolean testIfStatement2(String value) {
        if (value != null && value.length() != 0){
            return false;
        } else {
            return true;
        }

    }

测试所花时间的代码如下:

public static void main(String[] args) {

		String value1 = null;
		long startTime1 =System.nanoTime();
		for (long i=0; i< 100000000;i++) {
			TestUtil.testIfStatement1(value1);
		}
		long endTime1 =System.nanoTime();
		System.out.println("Time cost for testIfStatement1 is "+endTime1);

		String value2 = null;
		long startTime2 =System.nanoTime();
		for (long j=0; j< 100000000;j++) {
			TestUtil.testIfStatement2(value2);
		}
		long endTime2 =System.nanoTime();
		System.out.println("Time cost for testIfStatement2 is "+endTime2);

		TestUtil.testQueryParam();

		SpringApplication.run(LargestApplication.class, args);
	}

分别取值为:test, "" 和null 测试的结果如下:

操作符取值
test“”null
||773894902573100773984677463400774730049828900
&&773895147096200773984924305100774730324403600

 通过三组值的比较发现||的操作总是比&&的操作快。

于是又进一步查看两个函数的字节码:

发现唯一的不同的地方就是判断是否为null的时候的跳转目标不同,一个11(+10),一个是13(+12),难道是因为多跳了两个的缘故?

即使是如此,当判断的值不是null的时候,按理说,剩下的逻辑应该一样的了,时间也应该差不多,没想到的是也总是||的方法比较快。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值