c冒泡排序比java慢原因是什么。

gcc的版本是5.3.0开启编译优化-O2。java是1.8的server模式
a为a[10000]时java耗时50ms。c耗时75ms。
a为十万位是java耗时5秒,c耗时7.5秒。
为什么c会比java慢?有人试过吗?
c的冒泡

void BubbleSort(int a[])
{

    for(int i=0; i<len-1; i++)
    {

        for(int j=0; j<len-1-i; j++)
        {
            if(a[j]>a[j+1])
            {
                int tmp=a[j];
                a[j]=a[j+1];
                a[j+1]=tmp;
            }
        }
    }
}

java code

public static void bubbleSort(int[] a) {
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = 0; j < a.length - 1 - i; j++) {
                if (a[j] > a[j + 1]) {
                    int tmp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = tmp;
                }

            }
        }

    }

下面是完整代码,同志们可以自己机子跑跑看。
c的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/timeb.h>
#define GET_ARRAY_LEN(array,len){len = (sizeof(array) / sizeof(array[0]));}
int len;
int main()
{

//    int *a=malloc(300000000*sizeof(int));
//   len=300000000;
//   int a[10000];
//  GET_ARRAY_LEN(a,len);
    int *a=malloc(10000*sizeof(int));
    len=10000;

    for(int i=0; i<len; i++)
    {
        a[i]=len-i;
    }
//print(a);
    struct timeb startTime, endTime;
    ftime(&startTime);
    BubbleSort(a);
    ftime(&endTime);
    printf("%d \n",(endTime.time-startTime.time)*1000 + (endTime.millitm - startTime.millitm));
//print(a);

}

void BubbleSort(int a[])
{

    for(int i=0; i<len-1; i++)
    {

        for(int j=0; j<len-1-i; j++)
        {
            if(a[j]>a[j+1])
            {
                int tmp=a[j];
                a[j]=a[j+1];
                a[j+1]=tmp;
            }
        }
    }
}
void print(int a[])
{

    for(int i=0; i<len; i++)
    {
        printf(" %d",a[i]);
    }
    printf("\n");
}

java 完整代码

public class Sort {
    public static void main(String[] args) {
//         int[] a = getData(500000000);
        int[] a = getData(10000);
        // print(a);
        long start = System.currentTimeMillis();
        bubbleSort(a);
        System.out.println("use " + (System.currentTimeMillis() - start));

        // print(a);
    }

    public static void bubbleSort(int[] a) {
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = 0; j < a.length - 1 - i; j++) {
                if (a[j] > a[j + 1]) {
                    int tmp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = tmp;
                }

            }
        }

    }
}
阅读 4.5k
6 个回答

可能java编译器优化的更好。在leetcode上也时常看得到java的解法优于c/c++的解法。

~~ 最好把你的测试代码发出来,以及时间的计算方式
这种循环代码其实是有利于JIT编译器的优化的,除去JVM的启动时间,就算javac快也是有可能的

感觉和我的价值观相悖 ...

PS:机子上并没有 C 和 Java 的编辑器来 test

  1. 是否把数组初始化所用的时间也计算在内了?

  2. Java在多核平台下进行了优化,而C语言你得自己处理,是不是用C的单核跟Java的多核进行对比?就好比我在8核平台下测试的,Java默认情况下用到125%CPU,C只能用到85%

最后,这个好像也是题主问的 http://stackoverflow.com/ques...

经过我测试,还是C比较快一点,但是差距不大。
测试环境如下

Linux o-s 4.6.4-1-ARCH #1 SMP PREEMPT Mon Jul 11 19:12:32 CEST 2016 x86_64 GNU/Linux
Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz
8GB DDR3内存

java -showversion
openjdk version "1.8.0_112"
OpenJDK Runtime Environment (build 1.8.0_112-b15)
OpenJDK 64-Bit Server VM (build 25.112-b15, mixed mode)

gcc 版本 6.2.1 20160830 (GCC)
线程模型:posix

C冒泡排序测试

下面是C的代码,排序部分没有变。计时部分稍微修改了一下。

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

void bubbleSort(int* a,int length);

int main() 
{
    srand(time(NULL));
    int array[100000];
    for (int i = 0; i < 100000; i ++) {
        array[i] = rand();
    }

    clock_t starttime, endtime;
    double duration;
    starttime = clock();
    bubbleSort(array,100000);
    endtime = clock();
    duration = (double)(endtime -starttime)*1000.0/CLOCKS_PER_SEC;
    printf("use %f\n",duration);
    return 0;
}

void bubbleSort(int* a,int length) 
{
    for (int i = 0; i < length - 1; i++) {
        for (int j = 0; j < length - 1 - i; j++) {
            if (a[j] > a[j + 1]) {
                int tmp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = tmp;
            }
        }
    }
}

编译运行

/home/o/111 [o@o-s] [11:29]
> gcc Sort.c -o Sort -O2

/home/o/111 [o@o-s] [11:30]
> ./Sort 
use 15548.507000

使用clang编译

/home/o/111 [o@o-s] [12:06]
> clang-3.8 Sort.c -O2 -o Sort

/home/o/111 [o@o-s] [12:06]
> ./Sort 
use 13214.605000

java冒泡排序测试

java代码如下
没有修改计时代码,还是使用的System.currentTimeMillis(),使用System.nanoTime()精度会比较高。

import java.util.Random;

public class Sort {
    public static void main(String[] args) {
        Random random = new Random();
        int[] array = new int[100000];
        for (int i = 0; i < 100000; i ++) {
            array[i] = random.nextInt(100000);
        }

        long start = System.currentTimeMillis();
        bubbleSort(array);
        System.out.println("use " + (System.currentTimeMillis() - start));
    }

    public static void bubbleSort(int[] a) {
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = 0; j < a.length - 1 - i; j++) {
                if (a[j] > a[j + 1]) {
                    int tmp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = tmp;
                }
            }
        }
    }
}

运行测试(修改使用-server参数)

/home/o/111 [o@o-s] [11:45]
> javac -server Sort.java 

/home/o/111 [o@o-s] [12:02]
> java Sort 
use 19018

我在Ubuntu 14.04(i5-3230M)上的测试结果是:
在最坏情况下(时间复杂度为O(n^2))对10个数,进行1亿次冒泡排序,
Java计算速度接近GCC -O1优化的本地程序的速度,比GCC -O3慢.
代码和结果如下:
BubbleSort.c

/*
 * BubbleSort.c
 * Ubuntu-14.04(i5-3230M) GCC-4.8
 * 编译: gcc -O1 BubbleSort.c -o BubbleSort 运行: time ./BubbleSort 结果: 100000000 次 耗时 0m5.615s
 * 编译: gcc -O3 BubbleSort.c -o BubbleSort 运行: time ./BubbleSort 结果: 100000000 次 耗时 0m4.789s
 * */
#include <stdio.h>
#include <stdlib.h>
void bubble_sort(int array[], int size) {
    int i,j,temp;
    for (i=0;i<size;i++) {
        for (j=0;j<size-1-i;j++) {
            if (array[j] < array[j+1]) {
                temp = array[j];
                array[j] = array[j+1];
                array[j+1] = temp;
            }
        }
    }
}
int main(int argc, char *argv[]) {
    int size=10, c, i;
    int *array = malloc(size*sizeof(int));
    for (c=0;c<100000000;c++) {
        for (i=0;i<10;i++) array[i] = i; //数组赋值
        bubble_sort(array, size); //传递数组地址
    }
    for (i=0;i<size;i++) printf("%d ", array[i]);
    printf("\n");
    free(array);
    return 0;
}

BubbleSort.java

/*
 * BubbleSort.java
 * Ubuntu-14.04(i5-3230M) Java 1.7 HotSpot(TM) 64-Bit Server VM
 * 编译: javac BubbleSort.java
 * 100000000 次冒泡排序耗时:
 * time java BubbleSort 耗时 0m5.642s
 */
public class BubbleSort {
    public static int[] bubbleSort(int[] array) {
        int i,j,temp,size;
        size = array.length;
        for(i=0;i<size;i++) {
            for(j=0;j<size-1-i;j++) {
                if(array[j] < array[j+1]) {
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
        return array;
    }
    public static void main(String[] args) {
        int array[] = new int[10], size = array.length, c, i;
        for (c=0;c<100000000;c++) {
            for (i=0;i<size;i++) array[i] = i;
            array = bubbleSort(array);
        }
        for (i=0;i<size;i++) System.out.print(array[i]+" ");
        System.out.println();
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题