相同的 for 循环 为什么 Java 比 c 的速度快?

338 天前
 chaoschick
Java

public class DuffDevice {

private static int duff2(int count) {
int i = 0;
do {
++i;
} while (--count >0);
return i;
}

public static void main(String[] args) {
int duff;
long start, end;
DuffDevice duffDevice = new DuffDevice();

start = System.currentTimeMillis();
duff = duff2(Integer.MAX_VALUE - 7);
end = System.currentTimeMillis();
System.out.println(duff + " " + (end - start) + " ms");
}
}

C
#include <sys/time.h>
#include <stdio.h>

int duff(int count) {
}

int main(int argc, char* argv[]) {
struct timeval start_time, end_time;

gettimeofday(&start_time, NULL);

long count = 2147483640;
long i = 0;

do {
++i;
} while (--count);

gettimeofday(&end_time, NULL);

int total_time = 1000000 * (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_usec - start_time.tv_usec);
printf("%d us", total_time);
printf("\n");
printf("%.3f ms", (double) total_time / 1000);
printf("\n");

printf("%l", i);
return 0;
}

Java 耗时情况
2 ms

C 耗时情况
4638.628 ms

性能怎么会相差这么大?
3870 次点击
所在节点    程序员
23 条回复
xtreme1
338 天前
tool2d
338 天前
@xtreme1 被完全优化掉的不算。


long i = 0;
改成
volatile long i = 0;

时间就正常了。
chaoschick
338 天前
@xtreme1 能解释一下为什么两者性能如此悬殊的原因吗
chaoschick
338 天前
@tool2d 我试试
hefish
338 天前
java 的编译器高级。全优化掉了。
chaoschick
338 天前
@tool2d [admin@iZt4ngr7j75qbzgg9ilsifZ c]$ cat duff2.c
#include <sys/time.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
struct timeval start_time, end_time;

gettimeofday(&start_time, NULL);

long count = 2147483640;
volatile long i = 0;

do {
++i;
} while (--count);

gettimeofday(&end_time, NULL);

int total_time = 1000000 * (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_usec - start_time.tv_usec);
printf("%d us", total_time);
printf("\n");
printf("%.3f ms", (double) total_time / 1000);
printf("\n");

printf("%l", i);
return 0;
}
[admin@iZt4ngr7j75qbzgg9ilsifZ c]$ gcc duff2.c && ./a.out
4621705 us
4621.705 ms
wdlth
338 天前
我在我的电脑测试结果是:
0 us
0.000 ms
tool2d
338 天前
@chaoschick 4 秒正常的啊,我这里也是 4 秒。

0 秒那种都是编译器把循环优化掉了。
diivL
338 天前
gcc duff2.c -O3 && ./a.out
chaoschick
338 天前
public class DuffDevice {

private static long duff2(long count) {
long i = 0;
do {
++i;
} while (--count >0);
return i;
}

public static void main(String[] args) {
long duff;
long start, end;
DuffDevice duffDevice = new DuffDevice();

start = System.currentTimeMillis();
duff = duff2((long) Integer.MAX_VALUE - 7);
end = System.currentTimeMillis();
System.out.println(duff + " " + (end - start) + " ms");
}
}

输出
2147483640 639 ms

我改了一下 i 值的类型 耗时 变长了
所以 应该没把循环优化掉吧
chaoschick
338 天前
@diivL [admin@iZt4ngr7j75qbzgg9ilsifZ c]$ gcc duff2.c -O3 && ./a.out
3688484 us
3688.484 ms
diivL
338 天前
@chaoschick 你用的是 #6 的代码吗? 用你主贴的代码,然后用 gcc duff2.c -O3 && ./a.out
chaoschick
338 天前
@diivL #include <sys/time.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
struct timeval start_time, end_time;

gettimeofday(&start_time, NULL);

long count = 2147483640;
long i = 0;

do {
++i;
} while (--count);

gettimeofday(&end_time, NULL);

int total_time = 1000000 * (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_usec - start_time.tv_usec);
printf("%d us", total_time);
printf("\n");
printf("%.3f ms", (double) total_time / 1000);
printf("\n");

printf("%l", i);
return 0;
}
[admin@iZt4ngr7j75qbzgg9ilsifZ c]$ gcc duff2.c -O3 && ./a.out
1 us
0.001 ms

这是优化掉 for 循环了吗?
Ericcccccccc
338 天前
在 main 里做性能测试是无效行为.

而且 java 里有各种 jit, osr 之类的高级优化手段
iseki
338 天前
此外 Java 的 volatile 有额外的语义,所以也没法和 C 对应,这样做 microbench 可能你们很难说明什么问题
msg7086
338 天前
> 为什么
因为优化不一样。如果 Java 比 C 快很多,那说明 Java 上优化得比 C 狠,反之亦然。
Inn0Vat10n
338 天前
你这里出现这么离谱的结果, 首要原因是编译 C 代码时没开优化
Cookmilk
338 天前
C 是直接跑在电脑的 CPU 里,java 跑在虚拟机 CPU 里。测试 for 循环毫无意义。应该测试某一个算法。比如加密算法或者 md5 等等
mangojiji
338 天前
又见达夫设备。 ...
chaoschick
338 天前
以前我一直以为编译器优化能提升的性能很小,这次真是长见识了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1003556

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX