Lu与C/C++、Forcal、MATLAB、Python、Lua等各种语言的速度比较

来源:互联网 发布:mac系统菜单栏不见了 编辑:程序博客网 时间:2024/05/07 13:17
 

欢迎访问Lu程序设计

Lu与C/C++、Forcal、MATLAB、Python、Lua等各种语言的速度比较

    以下比较均是在同一台计算机上进行的,在其他计算机上结果会有所不同。

1 Lu与C/C++、Forcal、Lua的数值计算速度比较

    C/C++代码:

z=0.0;
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)))));
  }
}

    以上C/C++代码运行结果:z=19160.536601703152,耗时约1.328秒。

    Forcal计算结果z=19160.536601703152,耗时约1.828秒。

    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)))))endfunction z()local t = os.clock()local x=0local y=0local z=0for x=0,1,0.0011 do for y=1,2,0.0011 do    z=z+f(x,y) endendio.write(z)io.write(string.format(" Time Elapsed %f\n", os.clock() - t))endz()


    Lua运行结果:

19160.536601703 Time Elapsed 3.234000

    Lu代码:

main(:x,y,z,t)=
{
  t=clock(), z=0.0, x=0.0,
  while{x<=1.0,
    y=1.0,
    while{y<=2.0,
      z=z+cos(1.0-sin(1.2*(x+0.1)^(y/2.0-x)+cos(1.0-sin(1.2*(x+0.2)^(y/3.0-x))))-cos(1.0-sin(1.2*(x+0.3)^(y/4.0-x)))-cos(1.0-sin(1.2*(x+0.4)^(y/5.0-x)+cos(1.0-sin(1.2*(x+0.5)^(y/6.0-x))))-cos(1.0-sin(1.2*(x+0.6)^(y/7.0-x))))),
      y=y+0.0011
    },
    x=x+0.0011
  },
  o{"z=",z,",耗时约",[clock()-t]/1000.0,"秒。\r\n"}
};

    Lu运行结果:

z=19160.536601703152,耗时约2.656秒。

2 八皇后问题

    据测定,以下八皇后问题,Lu的运行速度约为C++的1/23,而Forcal的运行速度约为C++的1/10。

// 在运行不同的程序时,Lu的速度,从接近C++到只有C++速度的几十分之一。
// Lu的建议是:对运行时间较长的程序,如确有必要,设计成二级函数由Lu调用,从而获得接近C++速度的性能。
// Lu与C++是无缝链接的。故C++能实现的功能,借助二级函数,Lu完全可以实现。
// 但没有Lu支持的C++程序,将无法获得高效率地实时编译计算字符串表达式的功能。

// 据测定,以下八皇后问题,Lu的运行速度约为C++的1/23。
// 八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。
// 该问题是19世纪著名的数学家高斯1850年提出:在8×8格的国际象棋盘上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
// 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。
// 以下算法是从网上搜来的,该算法没有最终给出排列组合,仅仅给出有多少种组合,但是算法确实十分奥妙。

//Lu源程序
(::sum,upperlim)= sum=0, upperlim=1, SetStackMax(1000);
test(row, ld, rd : pos,p : sum,upperlim)=
{
    which
    {
        row != upperlim,
        {
            pos = {upperlim && [!!(row||ld||rd)]},
            while{ pos,
                p = pos&&(-pos),
                pos = pos -p,
                test[row+p, (ld+p)<<1, (rd+p)>>1]
            }
        },
        sum++
    }
};
main(:tm,n:sum,upperlim)=
{
    tm=clock(), n=15,
    upperlim=(upperlim<<n)-1,
    test(0,0,0),
    o["Queens=",n,",sum=",sum,",耗时约",[clock()-tm]/1000.0,"秒。\r\n"]
};

Lu运行结果:

    Queens=15,sum=2279184,耗时约136.703秒。

完成相同功能的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

3 Matlab与Lu普通函数调用效率

    Matlab 2009a的测试代码:

f=@(x,y,z,t)x+y+z;
tic;
s=0;
for x=0:1000
    for y=0:100
        for z=0:100
            s=s+f(x,y,z);
        end
    end
end
s
toc

s =

6.126720600000000e+009

Elapsed time is 9.546717 seconds.

    将函数写成m文件后效率会提高,如下例:

%file xyz.m
function c=xyz(x,y,z)
c=x+y+z;
end

    测试代码:

tic;
s=0;
for x=0:1000
    for y=0:100
        for z=0:100
            s=s+xyz(x,y,z);
        end
    end
end
s
toc

s =

6.126720600000000e+009

Elapsed time is 4.724592 seconds.

    Lu代码:

f(x,y,z)=x+y+z;
main(:t,s,x,y,z)=
t=clock(),
s=0,
x=0, while{x<=1000,
    y=0, while{y<=100,
        z=0, while{z<=100,
            s=s+f(x,y,z),
            z++
        },
        y++
    },
    x++
},
o{"s=",s,", time=",[clock()-t]/1000.};

    Lu运行结果:

s=6126720600, time=4.015

4 Matlab与Lu的递归函数调用效率

    以Fibonacci递归程序为例进行比较。

    Matlab 2009a的Fibonacci函数定义:

function k=fib(n)

if n == 0
    k=0;
    return;
else if n == 1
    k=1;
    return;
else
    k=fib(n - 1) + fib(n - 2);
    return;
end

end

    运行结果:

tic;
fib(30)
toc

ans =

    832040

Elapsed time is 26.315245 seconds.

    Lu的Fibonacci函数及代码:

SetStackMax(1000);
F(n)= which{
    n == 0,
        return(0),
    n == 1,
        return(1),
    return [F(n - 1) + F(n - 2)]
};
main(:t)= t=clock(), o{"F(30)=",F(30),", time=",[clock()-t]/1000.};

    Lu运行结果:

F(30)=832040, time=0.875

5 变步长辛卜生二重求积法

    C/C++代码:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include "time.h"
#include "math.h"

double simp1(double x,double eps);
void fsim2s(double x,double y[]);
double fsim2f(double x,double y);

double fsim2(double a,double b,double eps)
{
    int n,j;
    double h,d,s1,s2,t1,x,t2,g,s,s0,ep;

    n=1; h=0.5*(b-a);
    d=fabs((b-a)*1.0e-06);
    s1=simp1(a,eps); s2=simp1(b,eps);
    t1=h*(s1+s2);
    s0=1.0e+35; ep=1.0+eps;
    while (((ep>=eps)&&(fabs(h)>d))||(n<16))
    {
        x=a-h; t2=0.5*t1;
        for (j=1;j<=n;j++)
        {
            x=x+2.0*h;
            g=simp1(x,eps);
            t2=t2+h*g;
        }
        s=(4.0*t2-t1)/3.0;
        ep=fabs(s-s0)/(1.0+fabs(s));
        n=n+n; s0=s; t1=t2; h=h*0.5;
    }
    return(s);
}

double simp1(double x,double eps)
{
    int n,i;
    double y[2],h,d,t1,yy,t2,g,ep,g0;

    n=1;
    fsim2s(x,y);
    h=0.5*(y[1]-y[0]);
    d=fabs(h*2.0e-06);
    t1=h*(fsim2f(x,y[0])+fsim2f(x,y[1]));
    ep=1.0+eps; g0=1.0e+35;
    while (((ep>=eps)&&(fabs(h)>d))||(n<16))
    {
        yy=y[0]-h;
        t2=0.5*t1;
        for (i=1;i<=n;i++)
        {
            yy=yy+2.0*h;
            t2=t2+h*fsim2f(x,yy);
        }
        g=(4.0*t2-t1)/3.0;
        ep=fabs(g-g0)/(1.0+fabs(g));
        n=n+n; g0=g; t1=t2; h=0.5*h;
    }
    return(g);
}

void fsim2s(double x,double y[])
{
    y[0]=-sqrt(1.0-x*x);
    y[1]=-y[0];
}

double fsim2f(double x,double y)
{
    return exp(x*x+y*y);
}

int main(int argc, char *argv[])
{
    int i;
    double a,b,eps,s;
    clock_t tm;

    a=0.0; b=1.0; eps=0.0001;
    tm=clock();
    for(i=0;i<100;i++)
    {
    s=fsim2(a,b,eps);
    }
    printf("s=%e , 耗时 %d 毫秒。\n", s, (clock()-tm));
}

    C/C++结果:

    s=2.698925e+000 , 耗时 78 毫秒。

    -------

    matlab 2009a代码:

%file fsim2.m
function s=fsim2(a,b,eps)
    n=1; h=0.5*(b-a);
    d=abs((b-a)*1.0e-06);
    s1=simp1(a,eps); s2=simp1(b,eps);
    t1=h*(s1+s2);
    s0=1.0e+35; ep=1.0+eps;
    while ((ep>=eps)&&(abs(h)>d))||(n<16),
        x=a-h; t2=0.5*t1;
        for j=1:n
            x=x+2.0*h;
            g=simp1(x,eps);
            t2=t2+h*g;
        end
        s=(4.0*t2-t1)/3.0;
        ep=abs(s-s0)/(1.0+abs(s));
        n=n+n; s0=s; t1=t2; h=h*0.5;
    end
end

function g=simp1(x,eps)
    n=1;
    [y0,y1]=f2s(x);
    h=0.5*(y1-y0);
    d=abs(h*2.0e-06);
    t1=h*(f2f(x,y0)+f2f(x,y1));
    ep=1.0+eps; g0=1.0e+35;
    while (((ep>=eps)&&(abs(h)>d))||(n<16))
        yy=y0-h;
        t2=0.5*t1;
        for i=1:n
            yy=yy+2.0*h;
            t2=t2+h*f2f(x,yy);
        end
        g=(4.0*t2-t1)/3.0;
        ep=abs(g-g0)/(1.0+abs(g));
        n=n+n; g0=g; t1=t2; h=0.5*h;
    end
end

%file f2s.m
function [y0,y1]=f2s(x)
    y0=-sqrt(1.0-x*x);
    y1=-y0;
end

%file f2f.m
    function c=f2f(x,y)
    c=exp(x*x+y*y);
end

%%%%%%%%%%%%%

>> tic
for i=1:100
a=fsim2(0,1,0.0001);
end
a
toc

a =

    2.6989

Elapsed time is 0.995575 seconds.

    -------

    Lu代码:

fsim2s(x,y0,y1)=
{
    y0=-sqrt(1.0-x*x),
    y1=-y0
};
fsim2f(x,y)=exp(x*x+y*y);
//////////////////
simp1(x,eps : n,i,y0,y1,h,d,t1,yy,t2,g,ep,g0)=
{
    n=1,
    fsim2s(x,&y0,&y1),
    h=0.5*(y1-y0),
    d=abs(h*2.0e-06),
    t1=h*(fsim2f(x,y0)+fsim2f(x,y1)),
    ep=1.0+eps, g0=1.0e+35,
    while {((ep>=eps)&(abs(h)>d))|(n<16),
        yy=y0-h,
        t2=0.5*t1,
        i=1, while{i<=n,
            yy=yy+2.0*h,
            t2=t2+h*fsim2f(x,yy),
            i++
        },
        g=(4.0*t2-t1)/3.0,
        ep=abs(g-g0)/(1.0+abs(g)),
        n=n+n, g0=g, t1=t2, h=0.5*h
    },
    g
};

fsim2(a,b,eps : n,j,h,d,s1,s2,t1,x,t2,g,s,s0,ep)=
{
    n=1, h=0.5*(b-a),
    d=abs((b-a)*1.0e-06),
    s1=simp1(a,eps), s2=simp1(b,eps),
    t1=h*(s1+s2),
    s0=1.0e+35, ep=1.0+eps,
    while {((ep>=eps)&(abs(h)>d))|(n<16),
        x=a-h, t2=0.5*t1,
        j=1, while{j<=n,
            x=x+2.0*h,
            g=simp1(x,eps),
            t2=t2+h*g,
            j++
        },
        s=(4.0*t2-t1)/3.0,
        ep=abs(s-s0)/(1.0+abs(s)),
        n=n+n, s0=s, t1=t2, h=h*0.5
    },
    s
};

//////////////////

main(:t0,i,a)=
t0=clock(),
i=0, while{i<100, a=fsim2(0,1,0.0001), i++},
o{"a=",a,", time=",[clock()-t0]/1000.};

    Lu结果:

a=2.6989250006243033, time=0.657

    ---------

    本例C/C++、matlab、Lu运行耗时之比为 1:12.7:8.5 。

    =========

    以下将变步长辛卜生二重求积算法写成通用的函数。不再给出C/C++代码,因其效率不会发生变化。

    注意函数fsim2中增加了两个参数,函数句柄fsim2s用于计算二重积分时内层的上下限,函数句柄fsim2f用于计算积分函数的值。

    Matlab 2009a代码:

%file fsim2.m
function s=fsim2(a,b,eps,fsim2s,fsim2f)
    n=1; h=0.5*(b-a);
    d=abs((b-a)*1.0e-06);
    s1=simp1(a,eps,fsim2s,fsim2f); s2=simp1(b,eps,fsim2s,fsim2f);
    t1=h*(s1+s2);
    s0=1.0e+35; ep=1.0+eps;
    while ((ep>=eps)&&(abs(h)>d))||(n<16),
        x=a-h; t2=0.5*t1;
        for j=1:n
            x=x+2.0*h;
            g=simp1(x,eps,fsim2s,fsim2f);
            t2=t2+h*g;
        end
        s=(4.0*t2-t1)/3.0;
        ep=abs(s-s0)/(1.0+abs(s));
        n=n+n; s0=s; t1=t2; h=h*0.5;
    end
end

function g=simp1(x,eps,fsim2s,fsim2f)
    n=1;
    [y0,y1]=fsim2s(x);
    h=0.5*(y1-y0);
    d=abs(h*2.0e-06);
    t1=h*(fsim2f(x,y0)+fsim2f(x,y1));
    ep=1.0+eps; g0=1.0e+35;
    while (((ep>=eps)&&(abs(h)>d))||(n<16))
        yy=y0-h;
        t2=0.5*t1;
        for i=1:n
            yy=yy+2.0*h;
            t2=t2+h*fsim2f(x,yy);
        end
        g=(4.0*t2-t1)/3.0;
        ep=abs(g-g0)/(1.0+abs(g));
        n=n+n; g0=g; t1=t2; h=0.5*h;
    end
end

%file f2s.m
function [y0,y1]=f2s(x)
    y0=-sqrt(1.0-x*x);
    y1=-y0;
end

%file f2f.m
function c=f2f(x,y)
    c=exp(x*x+y*y);
end

%%%%%%%%%%%%%%%%

>> tic
for i=1:100
a=fsim2(0,1,0.0001,@f2s,@f2f);
end
a
toc

a =

    2.6989

Elapsed time is 1.267014 seconds.

    --------

    Lu代码:

simp1(x,eps,fsim2s,fsim2f : n,i,y0,y1,h,d,t1,yy,t2,g,ep,g0)=
{
    n=1,
    fsim2s(x,&y0,&y1),
    h=0.5*(y1-y0),
    d=abs(h*2.0e-06),
    t1=h*(fsim2f(x,y0)+fsim2f(x,y1)),
    ep=1.0+eps, g0=1.0e+35,
    while {((ep>=eps)&(abs(h)>d))|(n<16),
        yy=y0-h,
        t2=0.5*t1,
        i=1, while{i<=n,
            yy=yy+2.0*h,
            t2=t2+h*fsim2f(x,yy),
            i++
        },
        g=(4.0*t2-t1)/3.0,
        ep=abs(g-g0)/(1.0+abs(g)),
        n=n+n, g0=g, t1=t2, h=0.5*h
    },
    g
};

fsim2(a,b,eps,fsim2s,fsim2f : n,j,h,d,s1,s2,t1,x,t2,g,s,s0,ep)=
{
    n=1, h=0.5*(b-a),
    d=abs((b-a)*1.0e-06),
    s1=simp1(a,eps,fsim2s,fsim2f), s2=simp1(b,eps,fsim2s,fsim2f),
    t1=h*(s1+s2),
    s0=1.0e+35, ep=1.0+eps,
    while {((ep>=eps)&(abs(h)>d))|(n<16),
        x=a-h, t2=0.5*t1,
        j=1, while{j<=n,
            x=x+2.0*h,
            g=simp1(x,eps,fsim2s,fsim2f),
            t2=t2+h*g,
            j++
        },
        s=(4.0*t2-t1)/3.0,
        ep=abs(s-s0)/(1.0+abs(s)),
        n=n+n, s0=s, t1=t2, h=h*0.5
    },
    s
};

//////////////////

f2s(x,y0,y1)=
{
    y0=-sqrt(1.0-x*x),
    y1=-y0
};
f2f(x,y)=exp(x*x+y*y);

main(:t0,i,a)=
  t0=clock(),
  i=0, while{i<100, a=fsim2(0,1,0.0001,HFor("f2s"),HFor("f2f")), i++},
  o{"a=",a,", time=",[clock()-t0]/1000.};

    Lu运行结果:

a=2.6989250006243033, time=0.719

    --------

    本例matlab与Lu耗时之比为1.267014 :0.719。

6 Matlab与Lu动态内存管理效率

    matlab 2009a代码:

clear all
tic
s=0;
for k=1:1000
    for i=1:1000
        a={2,2,2,2};
        s=s+a{1};
    end
end
s
toc

s =

    2000000

Elapsed time is 5.030599 seconds.

    Lu代码:

main(:a,t0,s,k,i)=
t0=clock(),
s=0,
k=0, while{k<1000,
    i=0, while{i<1000, a=lu(2,2,2,2), s=s+a[1], i++},
    k++
},
o{"s=",s,", time=",[clock()-t0]/1000.};

    Lu运行结果:

s=2000000, time=0.703

7 Lu与VC动态数组存取效率测试

    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;
    __int64 i,k;
    __int64 *p;
    char ch;

    old=clock();
    for(i=0,k=0;i<=1000000;i++)
    {
        p=new __int64[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++:500000500000 运行时间:218 即: 0.218秒

    Lu源程序:

(:i,k,p,t)=
{   t=clock(),i=0,k=0,
    (i<=1000000).while
    {
        p=new[ints,5],
        A[p,3]=i, k=k+A[p,3],
        del[p],
    //实际上在这里不需要使用del函数,去掉此语句将更快
        i++
    },
    o{"结果=",k,", 时间=",[clock()-t]/1000.,"秒。\r\n"}
};

    Lu运行结果:

结果=500000500000, 时间=0.86秒。

    在该例子中,Lu的效率为VC的0.86/0.218=3.95分之一。若将new和del这两个函数移到循环体的外边,Lu的效率如下:

    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;
    __int64 i,k;
    __int64 *p;
    char ch;

    old=clock(); p=new __int64 [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++:200000010000000 运行时间:125 即: 0.125秒

    Lu源程序:

(:i,k,p,t)=
{   t=clock(),p=new[ints,5],i=0,k=0,
    (i<=20000000).while
    {
        A[p,3]=i, k=k+A[p,3],
        i++
    },
    del[p],
    //实际上在这里不需要使用del函数
    o{"结果=",k,", 时间=",[clock()-t]/1000.,"秒。\r\n"}
};

    Lu运行结果:

结果=200000010000000, 时间=7.922秒。

    在该例子中,Lu的速度为VC的7.922/0.125=63.376分之一。注意循环次数都增加到了20000000次。

8 一段有趣的程序

    在这个网页看到一篇各种语言运行速度比较的文章,摘抄如下:

— Erik Wrenholt (erik -at- timestretch.com) 2005-09-20

LanguageTime Relative SpeedC gcc-4.0.10.05 seconds 1.00 xocaml compiled 3.09.20.05 seconds 1.00 xSBCL 1.0.20.13 seconds 2.55 xJava 1.4.20.40 seconds 8.00 xIo 20070410 Vector1.40 seconds 28.09 xLua 5.11.50 seconds 30.00 xocaml bytecode 3.09.23.76 seconds 75.15 xPython 2.5.19.99 seconds 199.80 xGhostscript 8.5111.66 seconds 233.12 xPerl 5.8.6 Optimized12.37 seconds 247.34 xTCL 8.4 Optimized16.00 seconds 320.00 xPerl 5.8.621.75 seconds 435.00 xPHP 5.1.423.12 seconds 462.40 xJavascript SpiderMonkey v1.631.06 seconds 621.27 xRuby 1.8.434.31 seconds 686.18 xEmacs Lisp47.25 seconds 945.00 xApplescript71.75 seconds 1435.00 xIo 2007041085.26 seconds 1705.13 x
用以上网址提供的c代码与Lu比较,c代码改写为vs 2008可接受的形式,编译运行,结果如下:
#include "stdafx.h"#include <math.h>#include <time.h>#define BAILOUT 16#define MAX_ITERATIONS 1000int 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("*");elseprintf(" ");}}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用的时间与c++相比,为1.078:0.25=4.312:1。

    Lua的代码及运行时间。

#!/usr/local/bin/lua-- By Erik Wrenholtlocal BAILOUT = 16local MAX_ITERATIONS = 1000function iterate(x,y)local cr = y-0.5local ci = xlocal zi = 0.0local zr = 0.0local i = 0while 1 doi = i+1local temp = zr * zilocal zr2 = zr*zrlocal zi2 = zi*zizr = zr2-zi2+crzi = temp+temp+ciif (zi2+zr2 > BAILOUT) thenreturn iendif (i > MAX_ITERATIONS) thenreturn 0endendendfunction mandelbrot()local t = os.clock()for y = -39, 38 dofor x = -39, 38 doif (iterate(x/40.0, y/40) == 0) thenio.write("*")elseio.write(" ")endendio.write("\n")endio.write(string.format("Time Elapsed %f\n", os.clock() - t))endmandelbrot()


    运行输出图形与前面相同,仅给出运行时间:

Time Elapsed 0.860000

    Python的代码及运行时间。

#!/usr/local/bin/python# by Daniel Rosengrenimport sys, timestdout = sys.stdoutBAILOUT = 16MAX_ITERATIONS = 1000class 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 0t = time.time()Iterator()stdout.write('\nPython Elapsed %.02f' % (time.time() - t))


    运行结果:

Python Elapsed 2.84

    =======================

    完成相同功能的Lu代码如下:

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,o("\r\n"),x = -39,while{  x < 39,i = mandelbrot(x/40.0, y/40.0),which{i==0,o("*"),o(" ")},x++},y++},now=clock(),o["\r\nLu Elapsed ",(now-old)/1000.0]};


    运行时输出的图形与C程序相同,在演示程序DemoLu32.exe(这是个windows程序)中的运行时间为:

        Lu Elapsed 5.657

    从运行结果可看出,Lu用的时间与c++相比,为5.657:0.25=22.628:1。

    因C/C++、Forcal、Lua等均使用控制台程序,故设计加载Lu并演示以上程序的C/C++控制台程序如下:

#include <windows.h>#include <iostream>#include <math.h>#include "lu32.h"#pragma comment( lib, "lu32.lib" )using namespace std;void _stdcall LuMessage(wchar_t *pch) //输出动态库信息,该函数注册到Lu,由Lu二级函数调用{    wcout<<pch;}void main(void){    void *hFor;            //表达式句柄    luINT nPara;           //存放表达式的自变量个数    LuData *pPara;         //存放输入自变量的数组指针    luINT ErrBegin,ErrEnd; //表达式编译出错的初始位置和结束位置    int ErrCode1,ErrCode2; //错误代码    void *v;    wchar_t mandelbrot[]=L"mandelbrot(x, y : cr,ci,zi,zr,i,temp,zr2,zi2) =\r\n{\r\n cr = y - 0.5,\r\n ci = x,\r\n zi = 0.0,\r\n zr = 0.0,\r\n i = 0,\r\n (1).while {\r\n i ++,\r\n temp = zr * zi,\r\n zr2 = zr * zr,\r\n zi2 = zi * zi,\r\n zr = zr2 - zi2 + cr,\r\n zi = temp + temp + ci,\r\n if [zi2 + zr2 > 16, return (i)],\r\n if [i > 1000, return (0)]\r\n }\r\n }";//字符串表达式    wchar_t mymain[]=L"mymain (:i,x,y,old,now) = {\r\n old=clock(),\r\n y = -39,\r\n while{ y < 39,\r\n o(\"\r\n\"),\r\n x = -39,\r\n while{ x < 39,\r\n i = mandelbrot(x/40.0, y/40.0),\r\n which{ i==0,\r\n o(\"*\"),\r\n o(\" \")\r\n },\r\n x++\r\n },\r\n y++\r\n },\r\n now=clock(),\r\n o[\"\r\nLu Elapsed \",(now-old)/1000.0]\r\n}";           //字符串表达式    if(!InitLu()) return;  //初始化Lu    InsertKey("\0\0\0\0",4,luPubKey_User,LuMessage,NULL,NULL,1,v); //使Lu运行时可输出函数信息    ErrCode1=LuCom(mandelbrot,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式    ErrCode2=LuCom(mymain,0,0,0,hFor,nPara,pPara,ErrBegin,ErrEnd); //编译表达式    if(ErrCode1 || ErrCode2)    {        cout<<"表达式有错误!错误代码:"<<ErrCode1<<" "<<ErrCode2<<endl;    }    else    {        LuCal(hFor,pPara); //计算表达式的值    }    FreeLu();              //释放Lu}


    运行时输出的图形与C程序相同,运行时间为:

Lu Elapsed 2.063

    从运行结果可看出,Lu用的时间与c++相比,为2.063:0.25=8.252:1。

9 Lu与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秒(用秒表测量)。

    Lu程序:

f(k:i,n)= i=0,n=0, while{i<=k, n=n+i++}, n;
(:t)= t=clock(), o{"f(100000000)=",f(100000000),", time=",[clock()-t]/1000.};

    Lu运行结果:

f(100000000)=5000000050000000, time=14.797

    ======

    另一个测试程序:

    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秒(用秒表测量)。

    Lu程序:

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;
main(:t)= t=clock(), o{"g(12.3,7.89)=",g(12.3,7.89),", time=",[clock()-t]/1000.};

    Lu结果:

g(12.3,7.89)=404005.29176341009, time=3.43


版权所有© Lu程序设计 2002-2010,保留所有权利
E-mail: Lu@sina.com  QQ:630715621
最近更新:2011年10月19日