FORCAL与C/C++、MATLAB、Python、Lua等各种语言的速度比较
目 录
1与C++的速度比较 2 与MATLAB速度比较 |
3与Python速度比较 4 与Lua速度比较 |
很多人反对在各种编程语言之间进行比较,特别是单纯的运算速度比较,从某种意义上说,我也赞成这样的观点。但一个不容置疑的事实是,任何人在选择使用一种语言时,都进行了各种比较。确实,有比较才有选择。多一点了解,就多一种选择。实际上,我在设计Forcal时,就时时拿Forcal与各种语言进行比较,从而不断地提高它的性能。以下是Forcal与部分语言的速度比较,供大家参考。当然,仅比较运算速度,是非常片面的,特别是仅仅选择了一些程序片段做这种比较。如果有人对这些比较有异议,也欢迎畅所欲言。
同时期待有人给出其他一些比较。
1.1 纯数学函数运算速度比较
Forcal软件包中的测试程序ForcalTest中有一个函数speed,比较了Forcal与c++执行如下代码的运行速度:
for(x=0.0;x<=1.0;x=x+0.0011)
{
for(y=1.0;y<=2.0;y=y+0.0011)
{
z=z+cos(1.0-sin(1.2*pow(x+0.1,y/2.0-x)+cos(1.0-sin(1.2*pow(x+0.2,y/3.0-x))))-cos(1.0-sin(1.2*pow(x+0.3,y/4.0-x)))-cos(1.0-sin(1.2*pow(x+0.4,y/5.0-x)+cos(1.0-sin(1.2*pow(x+0.5,y/6.0-x))))-cos(1.0-sin(1.2*pow(x+0.6,y/7.0-x)))));
}
}
以下是ForcalTest中运行speed()的结果,相信用过ForcalTest的都可以看到:
FORCAL与VC的速度比较:
表达式:(x,y)=cos{1-sin[1.2*[x+0.1]^(y/2-x)+cos{1-sin[1.2*[x+0.2]^(y/3-x)]}]-cos
{1-sin[1.2*[x+0.3]^(y/4-x)]}-cos{1-sin[1.2*[x+0.4]^(y/5-x)+cos{1-sin[1.2*[x+0.5]
^(y/6-x)]}]-cos{1-sin[1.2*[x+0.6]^(y/7-x)]}}}
FORCAL正对表达式进行循环求和计算,请等待... ...
forcal计算结果:19160.536601703152 运行时间:1782 即: 1.782秒
VC++ 正对表达式进行循环求和计算,请等待... ...
VC++ 计算结果:19160.536601703152 运行时间:1391 即: 1.391秒
1.2 八皇后问题速度比较
我在OpenFC中进行了这种比较,据测定,以下八皇后问题,Forcal的运行速度约为C++的1/11。
// 在运行不同的程序时,Forcal的速度,从接近C++到只有C++速度的几十分之一。
// Forcal的建议是:对运行时间较长的程序,如确有必要,设计成二级函数由Forcal调用,从而获得接近C++速度的性能。
// Forcal与C++是无缝链接的。故C++能实现的功能,借助二级函数,Forcal完全可以实现。
// 但没有Forcal支持的C++程序,将无法获得高效率地实时编译计算字符串表达式的功能。
// 据测定,以下八皇后问题,Forcal的运行速度约为C++的1/11。
// 八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。
// 该问题是19世纪著名的数学家高斯1850年提出:在8×8格的国际象棋盘上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
// 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。
// 以下算法是从网上搜来的,该算法没有最终给出排列组合,仅仅给出有多少种组合,但是算法确实十分奥妙。
//Forcal源程序
i:(::sum,upperlim)= sum=0,upperlim=1,SetIntStackMax(1000);
i:test(row, ld, rd : pos,p : sum,upperlim)=
{
which
{ row != upperlim,
{ pos = and{upperlim , not[or(row , ld , rd)]},
while{ pos,
p = and(pos,-pos),
pos = pos -p,
test(row+p, shl(ld+p,1), shr(rd+p,1))
}
},
sum++
}
};
i:main(:tm,n:sum,upperlim)=
{
n=15,
tm=CalFun(5,"SetRunTime"),
OutNStr(" Queens:"),out[n],OutNStr(" "),
upperlim=shl(upperlim,n)-1,
test(0,0,0),
OutNStr("sum:"),out[sum],OutNStr(" "),
out[CalFun(5,"GetRunTime")-tm],OutNStr(" seconds.")
};
//完成相同功能的C++程序
/*
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
long sum=0,upperlim=1;
void test(long row, long ld, long rd)
{
if (row != upperlim)
{
long pos = upperlim & ~(row | ld | rd);
while (pos){
long p = pos& -pos;
pos -= p;
test(row+p, (ld+p)<<1, (rd+p)>>1);
}
}
else
sum++;
}
int main(int argc, char *argv[])
{
time_t tm;
int n=15;
if(argc!=1)n=atoi(argv[1]);
tm=time(0);
if((n<1)||(n>32))
{
printf(" heh..I can’t calculate that.\n");
exit(-1);
}
printf("%d Queens\n",n);
upperlim=(upperlim<<n)-1;
test(0,0,0);
printf("Number of solutions is %ld, %d seconds\n", sum,(int)(time(0)-tm));
}
*/
VC运行结果:
15 Queens
Number of solutions is 2279184, 6 seconds
OpenFC运行结果:
i: 1000 Queens:15 sum:2279184 66 seconds.
1.3 FcData与C++的速度比较
FcData是Forcal数据扩展动态库。以下比较大致体现了FcData的效率。
VC源程序:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <math.h>
#include <time.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
clock_t old,now;
long i,k;
long *p;
char ch;
old=clock();
for(i=0,k=0;i<=1000000;i++)
{
p=new long[5];
p[3]=i; k=k+p[3];
delete[] p;
}
now=clock();
cout<<"vc++:"<<setprecision(20)<<k;
cout<<" 运行时间:"<<now-old<<" 即: "<<(double)(now-old)/CLOCKS_PER_SEC<<"秒"<<endl<<endl;
cin>>ch;
return 0;
}
VC运行结果:
vc++:1784293664 运行时间:218 即: 0.218秒
OpenFC中的Forcal源程序:
i:NowFcDataNum[10],SetFcDataMax[2000000];
SetRunTime();
i:(:i,k,p)=
{ i=0,k=0,
(i<=1000000).while
{
p=new[int_s,5],
p.[3].set(i), k=k+p.[3].get(),
delete[p],
i++
},
k
};
GetRunTime();
OpenFC运行结果:
i: 1784293664
10.469
在该例子中,Forcal的效率比较低,只有VC的10.469/0.218=48.02293577981651分之一,原因是new和delete这两个函数耗时