几种语言向量计算效率比较

几种语言向量计算效率

测试语言:C++、Fortran、Java、Python、Octave、C#
分别使用gcc、gfortran、oracle-java8、python2、python3、octave、dotnet(其中python使用numpy库,且需要编译的语言编译时均不开-O优化)
测试的计算是求两个10,000,000的一维数组x,y欧氏距离的平方,x是1-10000000从前到后依次递增的向量,y是x的正弦值
Fortran程序:

PROGRAM MAIN
    integer N
    real*8,allocatable::x(:),y(:)
    read(*,*) N
    allocate(x(N))
    allocate(y(N))
    do i=1,N+1
        x(i)=i-1
        y(i)=sin(real(i)-1)
    end do
    do i=1,N+1
        x(i)=(x(i)-y(i))*(x(i)-y(i))
    end do
    do i=2,N+1
        x(1)=x(1)+x(i)
    end do
    write(*,*) x(1)
    deallocate(x)
    deallocate(y)
end

C++程序:

#include <cmath>
#include <cstdio>
int main(){
    double *x,*y;
    int N;
    scanf("%d",&N);
    x=(double*)malloc(sizeof(double)*N);
    y=(double*)malloc(sizeof(double)*N);
    for(unsigned i=0;i<N;i++) {x[i]=i;y[i]=sin(i);}
    for(unsigned i=0;i<N;i++) x[i]=(x[i]-y[i])*(x[i]-y[i]);
    for(unsigned i=1;i<N;i++) x[0]+=x[i];
    printf("%.16e\n",x[0]);
    free(x);
    free(y);
    return 0;
}

Java程序:

import java.util.*;
public class speedtest{
    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        int N=in.nextInt();
        double[] x=new double[N];
        double[] y=new double[N];
        for(int i=0;i<N;i=i+1){
            x[i]=i;
            y[i]=Math.sin(i);
        }
        for(int i=0;i<N;i=i+1){
            x[i]=(x[i]-y[i])*(x[i]-y[i]);
        }
        for(int i=1;i<N;i=i+1){
            x[0]=x[0]+x[i];
        }
        System.out.println(x[0]);
    }
}

Python程序:

import math
import numpy as np
N=input()
N=int(N)
x=np.zeros(N)
y=np.zeros(N)
for i in range(N):
    x[i]=i
    y[i]=math.sin(i)
x=x-y
sum=np.vdot(x,x)
print(sum)

C#程序:

using System;
namespace csharp
{
    class Program
    {
        static void Main(string[] args)
        {   
            int N;
            N=Convert.ToInt32(Console.ReadLine());
            double[] x=new double[N];
            double[] y=new double[N];
            for(int i=0;i<N;i++){
                x[i]=i;
                y[i]=Math.Sin(i);
            }
            for(int i=0;i<N;i++){
                x[i]=(x[i]-y[i])*(x[i]-y[i]);
            }
            for(int i=1;i<N;i++){
                x[0]=x[0]+x[i];
            }
            Console.WriteLine(x[0]);
        }
    }
}

octave程序(.m):

N=input('');
x=zeros(1,N);
y=zeros(1,N);
for i=1:N+1;
    x(1,i)=i-1;
    y(1,i)=sin(i-1);
end
x=x-y;
x*x'

通过shell中的time进行计时,得到测试结果如下:

------------------------------------------------------
fortran:
   3.3333338333333678E+020

real    0m0.464s
user    0m0.384s
sys 0m0.080s
------------------------------------------------------
c++:
3.3333328333334505e+20

real    0m0.615s
user    0m0.554s
sys     0m0.060s
------------------------------------------------------
java:
3.3333328333334505E20

real    0m4.295s
user    0m4.228s
sys     0m0.072s
------------------------------------------------------
python:
3.333332833333263e+20

real    0m4.593s
user    0m4.540s
sys     0m0.547s
------------------------------------------------------
python3:
3.333332833333263e+20

real    0m5.426s
user    0m5.475s
sys     0m0.387s
------------------------------------------------------
c#(.Net core):
3.33333283333345E+20

real    0m3.049s
user    0m3.577s
sys     0m0.376s
------------------------------------------------------
octave:
3.3333e+20

real    2m24.650s
user    2m24.417s
sys     0m0.432s

可以看到Fortran和C++的运行效率远高于其他语言。
而对比Fortran和C++的效率可以看到Fortran比C++略快,不过由于本身计算时间较短,而且仅测试了一次,所以会有一些随机误差影响测试结果。可以认为Fortran和C++计算效率基本不相上下。

C#(.Net core)的效率慢于Fortran、C++,快于Java、Python,而且由于刚接触.Net core不是很会用dotnet,直接使用dotnet run在项目文件里执行的启动时间消耗很多,数组维度为1000时就需要2-3s的时间,因此实际上C#(.Net core)的效率应该更高。

Java、Python2、Python3的计算时间差距不大,其中Java略快一点,同样考虑随机误差基本上Python2和Java效率相近,而Python3则比Python2略慢一些。

Octave就不说了,符号计算支持不好,计算效率又低,也就只能解解小线性方程组了。

进一步增加数组维度采用100,000,000的数组进行测试,结果为:

------------------------------------------------------
fortran:
   3.3333333833325327E+023

real    0m5.936s
user    0m5.389s
sys     0m0.516s
------------------------------------------------------
c++:
3.3333332833330380e+23

real    0m5.892s
user    0m5.376s
sys     0m0.516s
------------------------------------------------------
java:
3.333333283333038E23

real    0m47.189s
user    0m46.745s
sys     0m0.436s
------------------------------------------------------
c#(.Net core):
3.33333328333304E+23

real    0m8.819s
user    0m8.375s
sys     0m0.795s

测试使用的机器内存为4G,在使用Python计算时会发生内存占用过高而死机的情况,未进行测试,octave也没有进行测试(没什么意义了)。

从测试结果来看,C++、Fortran依旧不相上下,而C#随着计算量的增加其启动时间也被掩盖,对比10,000,000的情况可以看到实际上C#效率并不比C++和Fortran差多少,量级上来说是一样的。而java的效率也没有明显不同,与剩余三个语言相比,时间高了一个量级。内存占用情况,除了Python直接死机以外,几个测试过的语言内存占用基本都是1.6G左右,其中Fortran略小,只占1.4G(理论上2个100,000,000的双精度数组应该是1.52G的内存占用,Fortran这个1.4G比较奇怪,不知道怎么优化的)。

可以看到大规模计算Fortran和C++的效率优势是其他语言无法相比的,但是语言本身学习难度和编写难度也很高。另外C#真的是一个非常优秀的语言,集Java与C++优势于一身,简直堪称完美,奈何微软不给力,哎。

猜你喜欢

转载自blog.csdn.net/artorias123/article/details/81781402