几种编程语言数值计算效率

测试语言: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){ Scannerin=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.554ssys 0m0.060s
------------------------------------------------------ java:
3.3333328333334505E20 real 0m4.295s user 0m4.228ssys 0m0.072s
------------------------------------------------------ python:
3.333332833333263e+20 real 0m4.593s user 0m4.540ssys 0m0.547s
------------------------------------------------------ python3:
3.333332833333263e+20 real 0m5.426s user 0m5.475ssys 0m0.387s
------------------------------------------------------ c#(.Net core):
3.33333283333345E+20 real 0m3.049s user 0m3.577ssys 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.376ssys 0m0.516s
------------------------------------------------------ java:
3.333333283333038E23 real 0m47.189s user 0m46.745ssys 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的效率,确实是一个很优秀的语言。


使用随机数代替原来的常值,维度设置为10,000,000则发生了一个很有意思的现象,java的运行速度突然暴增,仅次于C++和Fortran,但是python的速度没有太大变化,这可能是我最近换了Java环境的原因(⊙﹏⊙)(好像java9开始虚拟机的执行效率就提高了很多)。其他语言的计算情况基本没有变化,在使用dotnet编译出可执行文件后直接执行,速度和Java相近,现在来看这Java和C#真是有点意思。话说之前准备学Java的时候教材是Java8害怕有的代码照书上写有问题,就只装了Java8,后来系统和软件源更新,自动给我把Java10装上了还自动配置了环境,今天测试才发现原来Java这么快。这系统更新Python也从3.5升到3.6了怎么就没什么惊喜呢?
------------------------------------------------------ fortran:
1666141.1059189755 real 0m0.425s user 0m0.381s sys 0m0.044s
------------------------------------------------------ c++:
1.6665869264373838e+06 real 0m0.353s user 0m0.311ssys 0m0.040s
------------------------------------------------------ java: 1666339.9341341387
real 0m0.821s user 0m0.842ssys 0m0.085s
------------------------------------------------------ python:
1664946.3547216023 real 0m4.103s user 0m4.125ssys 0m0.598s
------------------------------------------------------ python3:
1666422.8935979758 real 0m4.313s user 0m4.345ssys 0m0.400s
------------------------------------------------------ .netcore(c#):
1666509.75499201 real 0m3.102s user 0m3.382s sys 0m0.284s

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信