`

对比C与JAVA运算符效率的六点无法解释的现象!

 
阅读更多

众所周知编程语言运算符的效率差异不小,今天博主对赋值运算,加法,减法,乘法,乘法,取模,位运算分别用C和JAVA进行了效率测试,产生了一些令我无法解释的测试结果,以此文章把问题记录下来,希望日后可以解决,也恭请各位大牛来帮忙,下面把我的测试出的问题罗列一下。

测试环境:CPU :i3-370M ;内存:4G; JAVA IDE:elipse ;C IDE:VC6.0,C-Free5.0。


问题一:到底是乘法效率高,还是除法效率高?

一些书籍记录乘法效率比除法效率高,比如对于浮点数m /= 2 应该改写成m *= 0.5于是我就做了如下的两个测试

C代码:

#include <stdio.h>
#include <time.h>

main(){ 
	long count = 100000000;
	float test = 1;
    int start_time, end_time;
  	
    start_time = clock();
    while(--count > 0)
    	test /= 2;
    end_time = clock();
    
    printf( "test /= 2耗时%d毫秒\n", (end_time - start_time));

    getchar(); 
} 
测试结果:平均在600ms

当我们把测试代码test /= 2 改为 test *= 0.5

测试结果:平均在:520ms

符合我们的期望值


再来看看同样的代码在JAVA上运行:

public class FuHaoCeshi {

	public static void main(String[] args){
		int count = 100000000;
		long start_time = 0;
		long end_time = 0;
		float test = 1;
		start_time = System.currentTimeMillis();
		
		 while(--count > 0)
		    	test /= 2;
		end_time = System.currentTimeMillis();
		System.out.println("test /= 2耗时"+ (end_time - start_time) + "ms");

		count = 100000000;
		start_time = System.currentTimeMillis();
		while(--count > 0)
			test *=0.5;
		end_time = System.currentTimeMillis();
		System.out.println("test *=0.5耗时"+ (end_time - start_time) + "ms");
		
		
	}

	
}
测试结果:

test /= 2耗时300ms
test *= 0.5耗时468ms

结果竟然与VC测试下的结果完全相反!除法效率居然更高- -!


问题二:长整型会造成时间翻倍?

我们把问题一JAVA程序中测试代码改成赋值运算:

public class FuHaoCeshi {

	public static void main(String[] args){
		int count = 100000000;
		long start_time = 0;
		long end_time = 0;
		int test = 1;
		start_time = System.currentTimeMillis();
		
		 while(--count > 0)
		    	test = 1;
		end_time = System.currentTimeMillis();
		System.out.println("test = 1耗时"+ (end_time - start_time) + "ms");

		
		
	}

	
}
测试结果:

test = 1耗时86ms

接下来我们把上述程序中int count改成long count看看结果:

测试结果:

test = 1耗时172ms

纳尼!时间居然翻倍了!


接下来用同样的代码用C语言测试:

两次结果都在350ms左右,无变化! 纠结!


问题三:除法和取模运算开销真的大吗?

取模是由除法实现的,除法和取模的开销比较大是大家的共识。于是我把上述的测试代码改成test %= 2;

测试结果:

test%=2耗时300ms。(与test = 1的时间消耗一模一样。)

而java测试结果:

test % =2耗时1084ms
test = 1耗时86ms

这个原因其实很好想,VC6.0做了优化把摸2运算优化成了位运算,于是我把test %= 2改成test %= 3

测试结果

test %= 3耗时1164ms,验证了我的想法。(JAVA的耗时无变化,貌似无优化)

但这不是重点,重点是我用C-Free测试了同样的代码:

#include <stdio.h>
#include <time.h>

main(){ 
	int count = 100000000;
	int test = 1;
    int start_time, end_time;
    
  	
    start_time = clock();
    while(--count > 0)
    	test %= 3;
    end_time = clock();
    
    printf( "耗时%d毫秒\n", (end_time - start_time));
    getchar(); 
} 
测试结果:

test%=3耗时92ms

于是我测试了 test%= 7,。。。31,的所有质数,结果一样!

这编译器怎么优化成一样的时间消耗?同样的CPU,里面的加法器,乘法器,除法器做的都是同样的事,怎么回事?


下面还有几个其他的小问题:

4.对于上面的程序循环count次什么也不做平均耗时:VC:320ms;C-Free:92ms,JVM:85ms,

为什么说C是执行效率最高的高级语言,JAVA由于有JVM层是执行效率慢的语言?

5.经过我各方面测试JAVA最耗时的运算是test %= 1,上述程序达到了3000ms,是对别的数取模耗时的3倍之多;

而在所有取模运算中test %= -1却是耗时最少的,两种情况怎么解释?

6.C-Free所有运算或者不做的效率几乎一样都在100ms左右,怎么做到的?


如果您能帮助博主解决上述问题麻烦您留言,或者您遇到了运算符效率方面不可思议的现象,也请留言,博主希望与大家探讨并完善博客。



==================================================================================================

作者:nash_ 欢迎转载,与人分享是进步的源泉!

转载请保留原文地址http://blog.csdn.net/nash_/article/details/8223162

===================================================================================================

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics