众所周知编程语言运算符的效率差异不小,今天博主对赋值运算,加法,减法,乘法,乘法,取模,位运算分别用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
===================================================================================================