热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么同样的代码java运行比c快

c语言:#include<stdio.h>#include<time.h>intmain(){clock_ttimeclock();int
c语言:
#include 
#include 

int main(){
clock_t time = clock();
int n = 0;
int i;

for(i=0; i<1000000000; i++){
n += i;
}

time = clock()-time;

printf("%d %lld\n", n, time/1000);

return 0;
}


java:
public class Main{
public static void main(String[] args){
long time = System.currentTimeMillis();
int n = 0;
int i;

for(i=0; i<1000000000; i++){
n += i;
}

time = System.currentTimeMillis()-time;

System.out.println(n+" "+time);
}
}

求大神解释?

35 个解决方案

#1


帮你定顶起

#2


clock返回的单位和秒没有直接关系。

#3


clock()这个函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数,在MSDN中称之为挂钟时间(wal-clock);

#4


clock算出来的不是以秒为单位的。。

#5


可以使用:
QueryPerformanceFrequency
QueryPerformanceCounter 
来精确计时。

#6


我把clock改成了gettimeofday()结果还是java运行快!

#7


因为Java 牛逼贝...

#8


 C用的是debug版么

#9


这故意构造的超过编译器循环展开优化和常数优化的能力, 就故意折腾编译器用的...

如果循环次数小于 65536 , 几个编译器都直接优化成了常数, 不过M$VC优化好像最差, 唉..
gcc没有优化成类似下面的目标代码, 太失望了:

int i , j;

for(i=0; i<1000000000; i+=1000){
for(j = 0; j < 1000; ++j)
n += i + j; 
}

#10


compiler 针对 java 作了优化?

#11


引用 楼主 chengliangqq 的回复:
c语言:
#include 
#include 

int main(){
clock_t time = clock();
int n = 0;
int i;

for(i=0; i<1000000000; i++){
n += i;
}

time = clock()-time;

printf("%d %lld\n", n, time/1000);

return 0;
}


java:
public class Main{
public static void main(String[] args){
long time = System.currentTimeMillis();
int n = 0;
int i;

for(i=0; i<1000000000; i++){
n += i;
}

time = System.currentTimeMillis()-time;

System.out.println(n+" "+time);
}
}

求大神解释?


你这一句printf("%d %lld\n", n, time/1000);错了!

clock()并不是返回毫秒数,而是计算机时钟发生器每秒产生的中断次数,这个中断次数是一个常量,当然不是1000,而是CLOCK_PER_SEC,这个常数不同机器是不同的,常见的是18.2或者10等等,你除以1000多除了好多倍,应修改为:

printf("%d %f\n", n, ( double )time / CLOCK_PER_SEC );

#12


引用 10 楼 AnYidan 的回复:
compiler 针对 java 作了优化?


java JIT 的代码应该做了循环展开优化, 没注意 gcc -O2 竟然没有包括  -funroll-loops , 试了下  gcc -O2  -funroll-loops 选项, gcc终于生成了比较正常的目标代码, 生成的目标代码等价于:  for(i=0; i<1000000000; i+=8)  n += 8*i + 28; 在我这的结果是:
没 -funroll-loops 选项时运行时间 500ms左右, 加了后100毫秒左右, Java 的结果 350毫秒左右

#13


晕,刚发现vc把CLOCK_PER_SEC搞成1000了,那就照以上改为用double算吧。

#14


看了下 VS2010 生成的代码, cl -O2 优化下的目标代码, M$的优化太有趣了, 目标代码等价于 :

int n0 , n1 , n2 , n3;
for(i=0; i<1000000000; i+=4) n0 += i, n1 += i + 1 , n2 += i + 2 , n3 += i + 3;
n = n0 + n1 + n2 + n3;

运行时间 210左右, 比Java快一点..

#15


计时标准搞错了吧。java不可能比C快的

#16


引用 9 楼 mLee79 的回复:
唉..
gcc没有优化成类似下面的目标代码, 太失望了


可能侦测溢出,所以没优化,long long n,应该0秒杀...

#17


引用 16 楼 angel_su 的回复:
Quote: 引用 9 楼 mLee79 的回复:

唉..
gcc没有优化成类似下面的目标代码, 太失望了


可能侦测溢出,所以没优化,long long n,应该0秒杀...


这个是正解, long long n , gcc 直接优化成 499999999500000000 鸟.  不过M$VC生成的代码还是一塌糊涂...

#18


唉, 试了下, M$VC VS2010, 64位的编译器优化基本上就打酱油的, 下面的代码, 32位编译器还能优化成 n += 8*i + 28;  64位的编译器却没有任何优化, 晕死了.. gcc 则不管咋写都是秒杀...


#include 
#include 


int main(){
long long n = 0;
int i;

for(i=0; i<1000000000; i+=8)  {
n += i + 0;
n += i + 1;
n += i + 2;
n += i + 3;
n += i + 4;
n += i + 5;
n += i + 6;
n += i + 7;
}

printf("%lld %d\n", n , clock() );

return 0;
}

#19


你是怎么运行的啊,我这执行的还是C快啊,java=1062 C=3有图有真像!!!

#20


没看清,JAVA返回的是毫秒数,呵呵

#21


我操尼玛,果然还是C快啊,RELEASE版的绝对比JAVA快啊

#22


VC下不做评论。

#23


同样的算法, c一般比java快。 

#24


RELEASE的绝对C快!!

#25


可怜那些老鸟都没试,就在那主观意淫,说循环数太大,扯编译器优化。。。,1000000000又没超过int范围 ,JAVA中int也是4字节,8楼才是大神,一语切中要害!!!!!!

#26


C语言还是不错的嘛~~~

#27


不可能  如果真是一样的 肯定是C更快的 

#28


java 还要跑虚拟机

#29


debug下说个蛋...

#30


C开优化了没有
汗哒哒

#31



楼主体会一下

#32


引用 25 楼 bug1190 的回复:
可怜那些老鸟都没试,就在那主观意淫,说循环数太大,扯编译器优化。。。,1000000000又没超过int范围 ,JAVA中int也是4字节,8楼才是大神,一语切中要害!!!!!!


看代码不认真,罚你重看,真的没有溢出?


for(i=0; i<1000000000; i++)
{
n += i;
}

#33


引用 32 楼 go_and_see 的回复:
Quote: 引用 25 楼 bug1190 的回复:

可怜那些老鸟都没试,就在那主观意淫,说循环数太大,扯编译器优化。。。,1000000000又没超过int范围 ,JAVA中int也是4字节,8楼才是大神,一语切中要害!!!!!!


看代码不认真,罚你重看,真的没有溢出?


for(i=0; i<1000000000; i++)
{
n += i;
}

有溢出怎么了,有溢出也是n溢出,有溢出JAVA不也照样有溢出吗?不是比执行效率吗,管溢出啥子事,再说了就算有溢出,溢出了也照加

#34


引用 33 楼 bug1190 的回复:
有溢出怎么了,有溢出也是n溢出,有溢出JAVA不也照样有溢出吗?不是比执行效率吗,管溢出啥子事, 再说了就算有溢出,溢出了也照加


溢出仍然计算加法,那是没有设置编译器优化才会这么做。MS的编译器默认选项,debug是没有优化的,release是按最快速度。优化和不优化,产生的目标文件不一样。

同样的代码,相似的优化方法,java最多接近C的运行速度。

#35


对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

使用电脑计时有时误差会很大,因为待测程序段的运行会影响电脑时钟。
将待测程序段循环足够多次,手动掐秒表计时可能更准确。
当然帖主这个肯定不用手动掐秒表了。

推荐阅读
author-avatar
萤之光
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有