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这两个函数耗时较长。若将new和delete这两个函数移到循环体的外边,Forcal的效率将大为提高,如下例:
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(); p=new long[5];
for(i=0,k=0;i<=20000000;i++)
{
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++:562894464 运行时间:125 即: 0.125秒
OpenFC中的Forcal源程序:
SetRunTime();
i:(:i,k,p)=
{ i=0,k=0,p=new[int_s,5],
(i<=20000000).while
{
p.[3].set(i), k=k+p.[3].get(),
i++
},
delete[p],
k
};
GetRunTime();
OpenFC运行结果:
i: 562894464
2.437
在该例子中,Forcal的速度为VC的2.437/0.125=19.496分之一。注意循环次数都增加到了20000000次。
1.4 与C++比较一个程序
在这个网页看到一篇各种语言运行速度比较的文章,摘抄如下:
— Erik Wrenholt (erik -at- timestretch.com) 2005-09-20
Language Time Relative Speed C gcc-4.0.1 0.05 seconds 1.00 x ocaml compiled 3.09.2 0.05 seconds 1.00 x SBCL 1.0.2 0.13 seconds 2.55 x Java 1.4.2 0.40 seconds 8.00 x Io 20070410 Vector 1.40 seconds 28.09 x Lua 5.1 1.50 seconds 30.00 x ocaml bytecode 3.09.2 3.76 seconds 75.15 x Python 2.5.1 9.99 seconds 199.80 x Ghostscript 8.51 11.66 seconds 233.12 x Perl 5.8.6 Optimized 12.37 seconds 247.34 x TCL 8.4 Optimized 16.00 seconds 320.00 x Perl 5.8.6 21.75 seconds 435.00 x PHP 5.1.4 23.12 seconds 462.40 x Javascript SpiderMonkey v1.6 31.06 seconds 621.27 x Ruby 1.8.4 34.31 seconds 686.18 x Emacs Lisp 47.25 seconds 945.00 x Applescript 71.75 seconds 1435.00 x Io 20070410 85.26 seconds 1705.13 x 我用以上网址提供的c代码与forcal比较,c代码改写为vs 2008可接受的形式,编译运行,结果如下:
#include "stdafx.h" #include <math.h> #include <time.h> #define BAILOUT 16 #define MAX_ITERATIONS 1000 int mandelbrot(double x, double y) { double cr = y - 0.5; double ci = x; double zi = 0.0; double zr = 0.0; int i = 0; while(1) { i ++; double temp = zr * zi; double zr2 = zr * zr; double zi2 = zi * zi; zr = zr2 - zi2 + cr; zi = temp + temp + ci; if (zi2 + zr2 > BAILOUT) return i; if (i > MAX_ITERATIONS) return 0; } } int _tmain (int argc, _TCHAR* argv[]) { clock_t old,now; old=clock(); int x,y; for (y = -39; y < 39; y++) { printf("\n"); for (x = -39; x < 39; x++) { int i = mandelbrot(x/40.0, y/40.0); if (i==0) printf("*"); else printf(" "); } } printf ("\n"); now=clock(); double query_time = ((double)(now-old))/CLOCKS_PER_SEC; printf ("C Elapsed %0.2f\n", query_time); return 0; }* * * * * *** ***** ***** *** * ********* ************* *************** ********************* ********************* ******************* ******************* ******************* ******************* *********************** ******************* ******************* ********************* ******************* ******************* ***************** *************** ************* ********* * *************** *********************** * ************************* * ***************************** * ******************************* * ********************************* *********************************** *************************************** *** ***************************************** *** ************************************************* *********************************************** ********************************************* ********************************************* *********************************************** *********************************************** *************************************************** ************************************************* ************************************************* *************************************************** *************************************************** * *************************************************** * ***** *************************************************** ***** ****** *************************************************** ****** ******* *************************************************** ******* *********************************************************************** ********* *************************************************** ********* ****** *************************************************** ****** ***** *************************************************** ***** *************************************************** *************************************************** *************************************************** *************************************************** ************************************************* ************************************************* *************************************************** *********************************************** *********************************************** ******************************************* ***************************************** ********************************************* **** ****************** ****************** **** *** **************** **************** *** * ************** ************** * *********** *********** ** ***** ***** ** * * * * C Elapsed 0.25 请按任意键继续. . .
运行结果:
我的Forcal代码,在ForcalTest中运行如下:
mandelbrot(x, y : cr,ci,zi,zr,i,temp,zr2,zi2) = { cr = y - 0.5, ci = x, zi = 0.0, zr = 0.0, i = 0, (1).while { i ++, temp = zr * zi, zr2 = zr * zr, zi2 = zi * zi, zr = zr2 - zi2 + cr, zi = temp + temp + ci, if [zi2 + zr2 > 16, return (i)], if [i > 1000, return (0)] } }; main (:i,x,y,old,now) = { old=clock(), y = -39, while{ y < 39, PrintStr("\013\010"), x = -39, while{ x < 39, i = mandelbrot(x/40.0, y/40.0), which{ i==0, PrintStr("*"), PrintStr(" ") }, x++ }, y++ }, PrintStr("\013\010"), now=clock(), (now-old)/1000 }
运行结果:
从运行结果可看出,Forcal用的时间与c++相比,为1.141:0.25=4.564:1。
如果将Forcal代码中的自动变量改成模块变量,运算速度将加快:
mandelbrot(x, y :: cr,ci,zi,zr,i,temp,zr2,zi2) = { cr = y - 0.5, ci = x, zi = 0.0, zr = 0.0, i = 0, (1).while { i ++, temp = zr * zi, zr2 = zr * zr, zi2 = zi * zi, zr = zr2 - zi2 + cr, zi = temp + temp + ci, if [zi2 + zr2 > 16, return (i)], if [i > 1000, return (0)] } }; main (::i,x,y,old,now) = { old=clock(), y = -39, while{ y < 39, PrintStr("\013\010"), x = -39, while{ x < 39, i = mandelbrot(x/40.0, y/40.0), which{ i==0, PrintStr("*"), PrintStr(" ") }, x++ }, y++ }, PrintStr("\013\010"), now=clock(), (now-old)/1000 }
运行时间为:0.81299999999999994秒
这次,Forcal用的时间与c++相比,为0.813:0.25=3.252:1。
2 与MATLAB速度比较[返回页首]
以下是以前我在SimWe仿真论坛的一个帖子,发表于 2004-2-14 21:49,OpneFC版本也是以前的,大家参考一下。也许Matlab的新版本提高了速度,但未进行比较。
【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! 我想测试一下OpenFC的速度,我知道MATLAB 6.5的运行速度非常快,想与它作个比较,但我没有MATLAB 6.5,因此想在这里请大家帮个忙。该程序段用C++描述为: s=0.0; for(x=0.0;x<=1.0;x=x+0.0011) {for(y=1.0;y<=2.0;y=y+0.0009) s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2))))); } //输出s的值和运行时间。 请用MATLAB 6.5的for循环和采用向量化方法用sum函数分别计算一下。 然后用OpenFC计算一下,OpenFC的下载地址为 http://www1.skycn.com/soft/14414.html 用OpenFC计算的源程序为: SetRunTime(); //计时开始; (:x,y,s)=one {s=0,x=0, for{le(x,1), //for循环算法; y=1, for{le(y,2), s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2))))), y=y+0.0009 }, x=x+0.0011 }, out(s) }; str["For_Time:"]+GetRunTime(); //计时结束; SetRunTime(); //计时开始; "f"(x,y)=cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2))))); sum[#"f",0,0,1,0.0011,1,2,0.0009]; //用sum函数计算; str["Sum_Time:"]+GetRunTime(); //计时结束; taohe回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! Wanglu == OpenFC的作者? 我没有OpenFC,所以无法测试,不过看起来差别应该不大,因为matlab利用blas作为矩阵或者向量的算法,已经最大限度的利用了cpu L2 cache,我想如果matlab慢的话,也不会有太大的差别。 盼望看到大家的测试结果。 blast回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! [code]%============================ function [t1,t2,t3]=asad() t1=cputime; s=0.0; for x=0.0:0.0011:1.0; for y=1.0:0.0009:2.0;2; s=s+cos(1-sin(1.2*x^(y/2)+cos(1-sin(1.2*y^(x/2))))); end end t1=cputime-t1; answer1=s 循环方法结束 %====================== t2=cputime; s=0.0; x=0.0:0.0011:1.0; y=1.0:0.0009:2.0;2; for i=1:910 for j=1:1112 s=s+cos(1-sin(1.2*x(i)^(y(j)/2)+cos(1-sin(1.2*y(j)^(x(i)/2))))); end end t2=cputime-t2; answer2=s 半向量法 %========================= t3=cputime; x=zeros(910,1112);y=zeros(910,1112); x1=0.0:0.0011:1.0; y1=1.0:0.0009:2.0;2; for i=1:910 x(i,: )=x1(i); end for i=1:1112 y(:,i)=y1(i); end s=cos(1-sin(1.2.*x.^(y./2)+cos(1-sin(1.2.*y.^(x./2))))); a=sum(sum(s)); t3=cputime-t3; answer3=a %结果输出,这里和上两个方法结果不同……不知道是哪里问题, %不过不影响计算时间 %%向量法结束 %=========================== [/CODE] 写个M函数 别人可以直接用这个验证了 blast回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! 感觉用向量法写,很不适应…… 还有,上面代码里面有个错误。不知道是哪里来的,向量法的函数不好调~ wanglu回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! 感谢blast 的测试,我想OpenFC和MATLAB在同一个机器上运行才能比较速度,在这里我只能给出在我的计算机上OpenFC的运行结果: 0. 1008606.649474411 0. For_Time: 2.69 0. 1008606.64947441 Sum_Time: 1.98 另外,我在附件中给出了OpenFC程序,请下载测试。再次感谢! blast回复: 回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! 引用: wanglu wrote: 感谢blast 的测试,我想OpenFC和MATLAB在同一个机器上运行才能比较速度,在这里我只能给出在我的计算机上OpenFC的运行结果: 0. 1008606.649474411 0. For_Time: 2.69 0. 1008606.64947441 Sum_Time: 1.98 另外,我在附件中给出了OpenFC程序,请下载测试。再次感谢! 很多人很在意自己的机器清洁,不愿意装过多程序吧……………… OpenFC1计算开始... ... 0. 1008606.649474411 0. For_Time: 1.453 0. 1008606.64947441 Sum_Time: 1.219 OpenFC1计算结束。 [t1,t2,t3]=asad answer1 = 1.008606649474410e+006 answer2 = 1.008606649474410e+006 answer3 = 1.011793351473273e+006 t1 = 2.64100000000000 t2 = 2.45300000000000 t3 = 0.87500000000000 我的最后一个算法比你的openfc快很多呀 wanglu回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! blast,您好: 我看不懂您的第三个算法中的以下两句: s=cos(1-sin(1.2.*x.^(y./2)+cos(1-sin(1.2.*y.^(x./2))))); a=sum(sum(s)); 不过MATLAB的向量化的sum函数速度的确快。 我想用一元函数比较会更好些,因为比较的结果可能相同。 我的OpenFC程序如下: SetCycleMax[100000000]; SetRunTime(); //计时开始; (:x,y,s)=one {s=0,x=0, for{le(x,1234), //for循环算法; s=s+cos(1-sin(1.2*x^(0.12/2)+cos(1-sin(1.2*0.12^(x/2))))), x=x+0.0011 }, out(s) }; str["For_Time:"]+GetRunTime(); //计时结束; SetRunTime(); //计时开始; "f"(x)=cos(1-sin(1.2*x^(0.12/2)+cos(1-sin(1.2*0.12^(x/2))))); sum[#"f",0,0,1234,0.0011]; //用sum函数计算; str["Sum_Time:"]+GetRunTime(); //计时结束; OpenFC运行结果如下: OpenFC1计算开始... ... 0. 0. 1087309.11281616 0. For_Time: 3.13 0. 1087309.112815978 Sum_Time: 2.47 OpenFC1计算结束。 请再用MATLAB 6.5的for循环和采用向量化方法用sum函数分别计算一下。 再次麻烦blast或者其他各位了。 blast回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! 速度还没有你原来那两个函数快呀 OpenFC1计算开始... ... 0. 0. 1087309.11281616 0. For_Time: 2.032 0. 1087309.112815978 Sum_Time: 1.656 OpenFC1计算结束。 至于那两句嘛 s=cos(1-sin(1.2.*x.^(y./2)+cos(1-sin(1.2.*y.^(x./2))))); .*与.^和./是专门针对同样大小矩阵的运算方式分别对应1X1阶矩阵的*与^和/ 含义就是分别对每个MxN矩阵上每个位置上的值进行*与^和/运算,最后的结果是同样的MxN矩阵 上面的自变量x y与结果S都是同样大小的矩阵 a=sum(sum(s)); sum(sum(s))是把S矩阵中每个分元素相加起来的意思 a=[1,2;3,4] a = 1 2 3 4 >> sum(a) ans = 4 6 >> sum(sum(a)) ans = 10 taohe回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! 呵呵, 都怪我孤陋寡闻,不懂wanglu大侠的OpenFC,看了两位上面的帖子,大概有了一些概念,要做什么。于是也运行了一下上面的例子,我的测试环境: Pentium III 1GHz, 512 MB ram, Windows XP Pro English. matlab 6.5 (Faint, 从运行结果看起来你们的电脑都比我得快 ) 我的运行结果好像OpenFC快一些。 先来OpenFC的结果: 复制内容到剪贴板代码: OpenFC1计算开始... ... 0. 0. 1087309.11281616 0. For_Time: 2.864 0. 1087309.112815978 Sum_Time: 2.234 OpenFC1计算结束。 接着来matlab的结果: 复制内容到剪贴板代码: >> [t1 t2 t3] = asad answer1 = 1.008606649474410e+006 answer2 = 1.008606649474410e+006 answer3 = 1.008606649474359e+006 t1 = 4.01600000000002 t2 = 5.37700000000001 t3 = 2.94499999999999 >> to blast: 我这里运行的三种结果都是一样的。 blast回复: 回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! 引用: taohe wrote: to blast: 我这里运行的三种结果都是一样的。 不过你的结果也有误差,明显是运算中作了简化。不过会和我这里差这么多,太奇怪了 这很奇怪 我更改了内存单元大小选项,改成了long e,但是没有什么作用…… 希望有人能解答…… 难倒是……传说中的……bug……@_@……matlab或者其他什么(CPU?听说过以前PII有)的bug wanglu回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! 看了blast对下面两句的解释,我明白MATLAB向量运算的意义了,向量运算的确很好。 s=cos(1-sin(1.2.*x.^(y./2)+cos(1-sin(1.2.*y.^(x./2))))); a=sum(sum(s)); 同时感谢taohe 的测试,不过用OpenFC和MATLAB测试的不是同一段程序,但根据推算,运算速度应该差不多。 taohe回复: 回复: 回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢 引用: blast wrote: [quote]taohe wrote: to blast: 我这里运行的三种结果都是一样的。 不过你的结果也有误差,明显是运算中作了简化。不过会和我这里差这么多,太奇怪了 这很奇怪 我更改了内存单元大小选项,改成了long e,但是没有什么作用…… 希望有人能解答…… 难倒是……传说中的……bug……@_@……matlab或者其他什么(CPU?听说过以前PII有)的bug [/quote] 我有点两眼昏花,没有看仔细,而且我先是用缺省地数据格式显示结果的,也就是和你上面的结果类似是用科学技术发表时的结果,那是看起来三个结果真的是一样的,后来我用format long,多显示小数点位数,可是没有再检查。 有可能是浮点运算的问题。 zmhansys回复: 【讨论】谁能帮我用 MATLAB 6.5 测试一下运行速度,先谢谢了! Matlab 6.5下计算如下:(P4 2.6 256) answer1 = 1.0086e+006 answer2 = 1.0086e+006 answer3 = 1.0086e+006 ans = 2.7970 >>
3 与Python速度比较[返回页首]
3.1 在一个帖子中的速度比较
以下是我在csdn论坛的一个帖子,发表于2008-11-25 21:40:40,略去了部分帖子内容,大家参考一下。
帖子:大家看Forcal能像python或perl等一样用于脚本编程吗?同时比较一下它们的速度和效率? 以下是Forcal与Python 比较的源代码及结果: Python 程序: Python code>>> def f(k): n=0 i=0 while i <=k: n=n+i i=i+1 return n >>> f(100000000) 5000000050000000 在我的计算机上运行32秒。不知道Python中测时间的函数,用秒表测的。 OpenFC 程序: SetRunTime(); //设置运行时间 f(k:i,n)= i=0,n=0, (i <=k).while{n=n+i,i++}, n; f(100000000); GetRunTime(); //获得运行时间 运行结果: 5000000050000000 4.359 Forcal用了4.359秒。 另一个测试程序: Python 程序: Python code>>> def f(x,y): return math.cos(1-math.sin(1.2*(x+0.1)**(y/2-x)+math.cos(1-math.sin(1.2*(x+0.2)**(y/3-x))))-math.cos(1-math.sin(1.2*(x+0.3)**(y/4-x)))-math.cos(1-math.sin(1.2*(x+0.4)**(y/5-x)+math.cos(1-math.sin(1.2*(x+0.5)**(y/6-x))))-math.cos(1-math.sin(1.2*(x+0.6)**(y/7-x))))) >>> def g(m,n): x=0 i=0 while i <=m: j=0 while j <=n: x=x+f(i,j) j=j+0.01 i=i+0.01 return x >>> g(12.3,7.89) 404005.29176341009 Python 运行10秒。 OpenFC 程序: SetRunTime(); //设置运行时间 f(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))))); g(m,n:i,j,x)= x=0,i=0, (i <=m).while{ j=0, (j <=n).while{ x=x+f(i,j), j=j+0.01 }, i=i+0.01 }, x; g(12.3,7.89); GetRunTime(); //获得运行时间 运行结果: 404005.2917634101 2.219 Forcal用了2.219秒。
3.2 与Python比较一个程序
该程序使用本文1.4中的程序,前面有Forcal和c++的运行结果,这里仅给出Python的代码及运行时间。
#!/usr/local/bin/python # by Daniel Rosengren import sys, time stdout = sys.stdout BAILOUT = 16 MAX_ITERATIONS = 1000 class Iterator: def __init__(self): stdout.write('Rendering...') for y in range(-39, 39): stdout.write('\n') for x in range(-39, 39): i = self.mandelbrot(x/40.0, y/40.0) if i == 0: stdout.write('*') else: stdout.write(' ') def mandelbrot(self, x, y): cr = y - 0.5 ci = x zi = 0.0 zr = 0.0 i = 0 while True: i += 1 temp = zr * zi zr2 = zr * zr zi2 = zi * zi zr = zr2 - zi2 + cr zi = temp + temp + ci if zi2 + zr2 > BAILOUT: return i if i > MAX_ITERATIONS: return 0 t = time.time() Iterator() stdout.write('\nPython Elapsed %.02f' % (time.time() - t))
运行结果:
Python Elapsed 2.84
可以看出,Python运行此程序较慢(Forcal的快速版本运行时间为0.813秒)。
4.1 纯数学函数运算速度比较
Forcal软件包中的测试程序ForcalTest中有一个函数speed,比较了Forcal与c++执行如下代码的运行速度,现在与Lua同时作比较:
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秒
在OpenFC中完成相同功能的Forcal代码:
SetRunTime(); //设置运行时间
f(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)))));
g(:i,j,x)= x=0,i=0,
(i <=1).while{
j=1,
(j <=2).while{
x=x+f(i,j),
j=j+0.0011
},
i=i+0.0011
},
x;
GetRunTime(); //获得运行时间
OpenFC运行结果:
0.
19160.53660170315
1.859 //1.859秒
完成相同功能的Lua程序:
function f(x,y) return math.cos(1-math.sin(1.2*(x+0.1)^(y/2-x)+math.cos(1-math.sin(1.2*(x+0.2)^(y/3-x))))-math.cos(1- math.sin(1.2*(x+0.3)^(y/4-x)))-math.cos(1-math.sin(1.2*(x+0.4)^(y/5-x)+math.cos(1-math.sin(1.2*(x+0.5)^(y/6-x))))- math.cos(1-math.sin(1.2*(x+0.6)^(y/7-x))))) end function z() local t = os.clock() local x=0 local y=0 local z=0 for x=0,1,0.0011 do for y=1,2,0.0011 do z=z+f(x,y) end end io.write(z) io.write(string.format("Time Elapsed %f\n", os.clock() - t)) end z()
Lua运行结果:
D:\VC 2008\lua\Release>lua c.lua
19160.536601703Time Elapsed 3.234000
4.2 与Lua比较一个程序
该程序使用本文1.4中的程序,前面有Forcal和c++的运行结果,这里仅给出Lua的代码及运行时间。
#!/usr/local/bin/lua -- By Erik Wrenholt local BAILOUT = 16 local MAX_ITERATIONS = 1000 function iterate(x,y) local cr = y-0.5 local ci = x local zi = 0.0 local zr = 0.0 local i = 0 while 1 do i = i+1 local temp = zr * zi local zr2 = zr*zr local zi2 = zi*zi zr = zr2-zi2+cr zi = temp+temp+ci if (zi2+zr2 > BAILOUT) then return i end if (i > MAX_ITERATIONS) then return 0 end end end function mandelbrot() local t = os.clock() for y = -39, 38 do for x = -39, 38 do if (iterate(x/40.0, y/40) == 0) then io.write("*") else io.write(" ") end end io.write("\n") end io.write(string.format("Time Elapsed %f\n", os.clock() - t)) end mandelbrot()
运行输出图形与前面相同,仅给出运行时间:
Time Elapsed 0.860000
可以看出,Lua运行此程序的速度与Forcal基本相同(Forcal的快速版本运行时间为0.813秒)。
版权所有© Forcal数学软件 2002-2009,保留所有权利
E-mail: forcal@sina.com QQ:630715621
最近更新: 2009年06月10日
本文通过多个实例对比了Forcal与其他编程语言如C/C++、MATLAB、Python、Lua等在数学运算上的性能差异。
8069

被折叠的 条评论
为什么被折叠?



