程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Lu與C/C++、Forcal、MATLAB、Python、Lua等各種語言的速度比較

Lu與C/C++、Forcal、MATLAB、Python、Lua等各種語言的速度比較

編輯:C++入門知識

以下比較均是在同一台計算機上進行的,在其他計算機上結果會有所不同。

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))))) 
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運行結果:

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

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代碼與Lu比較,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用的時間與c++相比,為1.078:0.25=4.312:1。

    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

    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

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

    完成相同功能的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: [email protected]  QQ:630715621
最近更新:2011年10月19日

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved