java的性能比c的高?

hf1414 2007-12-22 10:48:36
昨天在实验室有人说java写的程序的速度比c写的程序的速度快,我说不可能,于是就和他打赌,分别写了下面这两个程序:
//c++版本
#include "windows.h"
#include <iostream>

using namespace std;

int fib(int n) {
if (n == 0 || n == 1)
return n;
else
return fib(n - 1) + fib(n - 2);
}

int main(void)
{
long sec = GetTickCount();
for (int i = 0; i < 36; i++) {
cout<<"i="<<i<<"==>"<<fib(i)<<endl;
}
sec = GetTickCount()-sec;
cout<<"Running Time:"<<sec<<"ms"<<endl;
return 0;
}
//java版本
package preformance;
public class Main {
public static final int fib(int n) {
if (n == 0 || n == 1)
return n;
else
return fib(n - 1) + fib(n - 2);
}

public static void main(String[] args) {

long sec = System.currentTimeMillis();
for (int i = 0; i < 36; i++) {
System.out.println("n=" + i + "=>" + fib(i));
}
sec=System.currentTimeMillis()-sec;
System.out.println("Running Time:" + sec + "ms\n");
}
}
分别运行,本以为打赌肯定赢了,没想到结果居然让我大跌眼镜——java版运行时间811毫秒,c++运行时间1362毫秒。事后,我想是不是java虚拟机采用了某种对函数调用的缓存的机制,使得想访问到fib(5)这样的函数的时候,不需要递归计算而是直接返回了fib(5)的值。由于fibonacci数列本身具有大量重叠的子问题,所以这种缓存机制正好使得程序变得像动态规划一样避免了大量子问题的计算,从而让它表面上跑的比c++的程序快了。

当然上面只是我一点不成熟的想法,我也不知道用什么办法去证实我的想法的正确性。

所以想向大家请教,有没有其他更合理的解释:为什么一个依靠虚拟机执行的语言竟然会比一个编译成机器码的语言的速度还快。或者您能帮我优化一下c++版的程序,让它在不改变算法的前提下能运行的比java版的快。谢谢了。
...全文
1161 56 打赏 收藏 转发到动态 举报
写回复
用AI写文章
56 条回复
切换为时间正序
请发表友善的回复…
发表回复
BYSF_XF 2012-10-26
  • 打赏
  • 举报
回复
编译器优化的结果,复杂的程序肯定是C的快。
zk69052 2012-10-09
  • 打赏
  • 举报
回复
不错,大多数情况下还是C语言性能高一些
propers 2010-12-06
  • 打赏
  • 举报
回复
你的C++代码信能太差,用我的 fib:
int fib(int n)
{
int nReturn;
int i = n;
int * nFunList = new int[i+1];
bzero(nFunList, sizeof(int) * ( i + 1 ) );
nFunList[i] = 1;
while(i > 1){
nFunList[i-1] += nFunList[i];
nFunList[i-2] += nFunList[i];
i--;
}
nReturn = nFunList[1];
delete [] nFunList;
return nReturn;
}
用你的代码,我机子用了0.976秒,
用我的代码我的机子只用了0.003秒,你看java怎么写速度可以到这个量级。
别进别人的全套,java虚拟机会在流程上做些优化。
hf1414 2008-05-20
  • 打赏
  • 举报
回复
前段时间,不知怎么的,我访问这个帖子会出现什么“缓存服务器错误”一直无法访问,后来时间一长就忘记了,今天来才看见这个帖子竟然有了那么多的回复,真的很感动,但在感动之余也有一点点的失望。

我是个学生,学校里的那些程序其实用c/c++或者java都无所谓,我自己用c/c++和用java写的程序的数量也都差不多,所以我发这个帖子的初衷并不是真正的比较java和c哪个的效率更高,而是希望通过比较来回答类似这样的一些问题,例如:如果一个程序需要用到大量的数字运算使用c还是java速度更快?如果一个程序有大量的IO操作使用c还是java效率更高?如果一个程序的核心算法涉及到大量的递归调用使用c还是java更好?……也许很多书上都回答过这些问题,但都只是泛泛而谈,我只是个学生算是个最初级的程序员,我最需要的其实是一些直观的比较的例子,而不是这种泛泛而谈的结论。


另外,我觉得自己的程序写的很不好,所以我也想看看高手们是如何通过把握语言的细节在不改变算法的前提下优化一段代码让程序跑的更快的。

看了上面那么多回复,真正对我有帮助的确很少……不过还是有几位大哥贴出了他们的代码,还有几位大哥给出了修改意见,非常感谢!

不过有的帖子就让人有点哭笑不得了——还用这么麻烦?你告诉他,JAVA真的效率高啊!以后JAVA的虚拟机就用JAVA语言去写吧,他就懵了——还好我比较的是c和java,要比较的是人和猴子那就麻烦了,人还是猴子变的呢。

半年之后才回帖,真是不好意思,写到这里估计也没人看了,不过还是回了,就算是做事情有始有终吧。
  • 打赏
  • 举报
回复
[Quote=引用 48 楼 hf1414 的回复:]
前段时间,不知怎么的,我访问这个帖子会出现什么“缓存服务器错误”一直无法访问,后来时间一长就忘记了,今天来才看见这个帖子竟然有了那么多的回复,真的很感动,但在感动之余也有一点点的失望。

我是个学生,学校里的那些程序其实用c/c++或者java都无所谓,我自己用c/c++和用java写的程序的数量也都差不多,所以我发这个帖子的初衷并不是真正的比较java和c哪个的效率更高,而是希望通过比较来回答类似这样的一些问题,例…
[/Quote]

让他用java写个rsa的实现,然后跟openssl的比一下.
独孤过儿 2008-05-20
  • 打赏
  • 举报
回复
[Quote=引用 51 楼 Demon__Hunter 的回复:]
这帖子的够老的~~~~~
java总体上的性能始终是跑不过c/c++~~~
但不排除例外的情况~~~~~
java程序运行在一个用c编写的jvm上,总体速度肯定不如c/c++,当程序代码几十万上百万的运行效率差异就明显看出来了~~~~~
[/Quote]
很显然,你不了解编译原理,也不了解编译、连接、运行的内部执行细节...
机智的呆呆 2008-05-20
  • 打赏
  • 举报
回复
这帖子的够老的~~~~~
java总体上的性能始终是跑不过c/c++~~~
但不排除例外的情况~~~~~
java程序运行在一个用c编写的jvm上,总体速度肯定不如c/c++,当程序代码几十万上百万的运行效率差异就明显看出来了~~~~~
iambic 2008-05-20
  • 打赏
  • 举报
回复
在这里,“有始有终”的唯一含义是记得结贴。
healer_kx 2008-05-20
  • 打赏
  • 举报
回复
呵呵。
浪客 2008-01-10
  • 打赏
  • 举报
回复
运行于虚拟机的java代码总体上应该不会比C快的。。
L_Spring 2008-01-10
  • 打赏
  • 举报
回复
这样比有意义吗?
两种语言的侧重点都不一样的
ttlyfast 2008-01-10
  • 打赏
  • 举报
回复
哪个代码能更有效的利用机器特性
那种代码9能更快
aChinese 2008-01-10
  • 打赏
  • 举报
回复
//java版本
package demo;
public class Demo2 {
static int[] temp = new int[36];

static int fib(int n){

if (temp[n] != -1)
return temp[n];

if (n == 0 || n == 1)
{
temp[n]= n;
} else {
temp[n] = fib(n - 1) + fib(n - 2);
}

return temp[n];
}

public static void main(String[] args)
{
for (int i = 0; i < 36; i++)
temp[i] = -1;

long sec = System.currentTimeMillis();
for (int i = 0; i < 36; i++)
{
System.out.println("n=" + i + "=> " + fib(i));
}
sec = System.currentTimeMillis()-sec;
System.out.println("Running Time:" + sec + "ms\n");
}
}
如果用java也这样写, 那么也是16ms
taodm 2008-01-08
  • 打赏
  • 举报
回复
“运行效率”早就不是差异。
C++比C快慢+10%到-10%
java则可以比C++快慢+20%到-20%
如果没有程序员的强力介入,java因为在一些场合有更好的解决方案而效率超出。
承认现实,单语言打天下的日子已经过去了。
CoffeeCN 2008-01-08
  • 打赏
  • 举报
回复
补充一下 int temp[36] 就是模拟虚拟机的“Java存在堆栈上的中间结果”
ttlyfast 2008-01-08
  • 打赏
  • 举报
回复

lz在比编译器吗?
CoffeeCN 2008-01-08
  • 打赏
  • 举报
回复
奔四2.0上
depC++ 4.9.9.2 Running Time:31ms
CoffeeCN 2008-01-08
  • 打赏
  • 举报
回复
“ 如果把Java原程序想象成我们的C++原程序,Java原程序编译后生成的字节码就相当于C++原程序编译后的80x86的机器码(二进制程序文件),JVM虚拟机相当于80x86计算机系统,Java解释器相当于80x86CPU。在80x86CPU上运行的是机器码,在Java解释器上运行的是Java字节码。

Java解释器相当于运行Java字节码的“CPU”,但该“CPU”不是通过硬件实现的,而是用软件实现的。Java解释器实际上就是特定的平台下的一个应用程序。只要实现了特定平台下的解释器程序,Java字节码就能通过解释器程序在该平台下运行,这是Java跨平台的根本。”


所以C/C++跟Java做速度比较,不能单纯的在代码上做比较,因为Java在解释过程中消耗的大量系统资源是被虚拟机占用,虚拟机才是Java的真正幕后“黑手”。

“ 每一个Java虚拟机都包含方法区(method area)和堆(heap),他们都被整个程序共享。堆栈块包含Java方法调用的状态。当一个线程调用一个方法时,Java虚拟机会将一个新的块压到Java堆栈中,当这个方法运行结束时,Java虚拟机会将对应的块弹出并抛弃。”


如果这个程序要跟Java比,就要这样写:


#include <iostream>
#include <windows.h>
using namespace std;

int temp[36];

int fib(int n){

if (temp[n] != -1)
return temp[n];

if (n == 0 || n == 1)
{
temp[n]= n;
} else {
temp[n] = fib(n - 1) + fib(n - 2);
}

return temp[n];
}

int main(void)
{
for (int i = 0; i < 36; i++)
temp[i] = -1;

long sec = GetTickCount();
for (int i = 0; i < 36; i++)
{
cout << "i=" << i << "==> " << fib(i) << "\n";
}
sec = GetTickCount()-sec;
cout << "Running Time:" << sec << "ms" << "\n";
}
healer_kx 2008-01-08
  • 打赏
  • 举报
回复
JVM可能对函数的调用结果产生缓存,

比如 形如 y = f(x)这样的函数, 如果JVM确定了它的实现满足数学函数y = f(x), 就是说自变量就一个x(自变量不仅仅是参数).
那么可以对f的调用进行缓存,

比如楼主求 菲薄数列, f(3) = 2,就是一个结果了, 根本无需多次调用.

但是C++程序没有一个VM来做这个事情,所以很多人写的代码可能比Java的慢, 而且输入越大, 越是可能吃亏.


int fib(int n) {
static int i = 0;
}
如果我们在这个地方加个变量, 计算函数调用的次数, 就发现很多人fib(8)调用了很多次.
Pipi0714 2008-01-08
  • 打赏
  • 举报
回复
没有意思?java说性能高就高吧,不用告诉正确答案。
加载更多回复(36)

15,440

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧