• 请不要在回答技术问题时复制粘贴 AI 生成的内容
chaoschick
V2EX  ›  程序员

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

  •  
  •   chaoschick · Dec 26, 2023 · 4504 views
    This topic created in 881 days ago, the information mentioned may be changed or developed.
    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

    性能怎么会相差这么大?
    23 replies    2023-12-27 14:32:47 +08:00
    xtreme1
        1
    xtreme1  
       Dec 26, 2023   ❤️ 3
    tool2d
        2
    tool2d  
       Dec 26, 2023   ❤️ 1
    @xtreme1 被完全优化掉的不算。


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

    时间就正常了。
    chaoschick
        3
    chaoschick  
    OP
       Dec 26, 2023
    @xtreme1 能解释一下为什么两者性能如此悬殊的原因吗
    chaoschick
        4
    chaoschick  
    OP
       Dec 26, 2023
    @tool2d 我试试
    hefish
        5
    hefish  
       Dec 26, 2023
    java 的编译器高级。全优化掉了。
    chaoschick
        6
    chaoschick  
    OP
       Dec 26, 2023
    @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
        7
    wdlth  
       Dec 26, 2023
    我在我的电脑测试结果是:
    0 us
    0.000 ms
    tool2d
        8
    tool2d  
       Dec 26, 2023
    @chaoschick 4 秒正常的啊,我这里也是 4 秒。

    0 秒那种都是编译器把循环优化掉了。
    diivL
        9
    diivL  
       Dec 26, 2023
    gcc duff2.c -O3 && ./a.out
    chaoschick
        10
    chaoschick  
    OP
       Dec 26, 2023
    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
        11
    chaoschick  
    OP
       Dec 26, 2023
    @diivL [admin@iZt4ngr7j75qbzgg9ilsifZ c]$ gcc duff2.c -O3 && ./a.out
    3688484 us
    3688.484 ms
    diivL
        12
    diivL  
       Dec 26, 2023   ❤️ 1
    @chaoschick 你用的是 #6 的代码吗? 用你主贴的代码,然后用 gcc duff2.c -O3 && ./a.out
    chaoschick
        13
    chaoschick  
    OP
       Dec 26, 2023
    @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
        14
    Ericcccccccc  
       Dec 26, 2023
    在 main 里做性能测试是无效行为.

    而且 java 里有各种 jit, osr 之类的高级优化手段
    iseki
        15
    iseki  
       Dec 26, 2023 via Android
    此外 Java 的 volatile 有额外的语义,所以也没法和 C 对应,这样做 microbench 可能你们很难说明什么问题
    msg7086
        16
    msg7086  
       Dec 26, 2023
    > 为什么
    因为优化不一样。如果 Java 比 C 快很多,那说明 Java 上优化得比 C 狠,反之亦然。
    Inn0Vat10n
        17
    Inn0Vat10n  
       Dec 26, 2023
    你这里出现这么离谱的结果, 首要原因是编译 C 代码时没开优化
    Cookmilk
        18
    Cookmilk  
       Dec 27, 2023 via iPhone
    C 是直接跑在电脑的 CPU 里,java 跑在虚拟机 CPU 里。测试 for 循环毫无意义。应该测试某一个算法。比如加密算法或者 md5 等等
    mangojiji
        19
    mangojiji  
       Dec 27, 2023
    又见达夫设备。 ...
    chaoschick
        20
    chaoschick  
    OP
       Dec 27, 2023 via Android
    以前我一直以为编译器优化能提升的性能很小,这次真是长见识了
    PTLin
        21
    PTLin  
       Dec 27, 2023   ❤️ 1
    这种代码不长的,而且是循环引起的性能问题,建议直接看汇编/字节码,来确定问题以及验证猜想。
    或者用完整的性能测试框架测试,避免出现一个优化后测试的,一个还是调试模式测试的的这种低级问题。
    debuggerx
        22
    debuggerx  
       Dec 27, 2023
    [为什么下面程序递归计算斐波那契数列 java 比 c++要快 - RednaxelaFX 的回答]( https://www.zhihu.com/question/56683164/answer/150190561)
    LiaoMatt
        23
    LiaoMatt  
       Dec 27, 2023
    C 代码的变量用 register 修饰会不会更快
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2823 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 108ms · UTC 15:22 · PVG 23:22 · LAX 08:22 · JFK 11:22
    ♥ Do have faith in what you're doing.