核心提示:好久没有关注freepascal和lazarus,前两天一看,lazarus居然已经发布了1.0正式版,下载了一个windows版,一试,感觉比较爽,IDE好像已经强过DELPHI7(我一直用DELPHI7),中文的问题好像已经没有了。有关生成的可执行的文件太大的问题也试了一下,缺省的文件还是比较大...
好久没有关注freepascal和lazarus,前两天一看,lazarus居然已经发布了1.0正式版,下载了一个windows版,一试,感觉比较爽,IDE好像已经强过DELPHI7(我一直用DELPHI7),中文的问题好像已经没有了。有关生成的可执行的文件太大的问题也试了一下,缺省的文件还是比较大的。试了它里面的几个例子,都是十几兆,把编译开关重新调整了一下,一个是除去调试信息,一个是作SMARTLINK,大小减少到2兆多,可以接受。不过有调试信息也是有意义的,出了问题可以知道是程序哪一行有问题。我原来看过几年前有人写过的一篇关于DELPHI和Freepascal的性能比较文章,说是DELPHI比Freepascal快差不多10-30%,在有数学函数的运算中,差距超过30%,但昨天我作的测试结果完全颠覆了这个说法。在我的测试中发现除了显示部分,Freepascal性能已经超过了DELPHI。
现在我把我昨天晚上作的关于DELPHI和freepascal的几个性能测试例子发布一下:
(1)平衡二叉树的创建
const
cBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
cBase64Len=Length(cBase64);
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
Node:TAVLTreeNode;
Image:TImage;
T1,T2:TDateTime;
begin
T1:=Now;
Tree.Clear;
RandSeed:=1;
DrawCount:=1;
for i:=1 to 20*10000 do
begin
DrawCount:=(DrawCount+1) mod 2;
Image:=TImage(FindComponent('Image'+IntToStr(DrawCount+1)));
// Image.Canvas.FillRect(Image.ClientRect);
// Tree.DrawTreeNode(Image.Canvas);
Node:=TAVLTreeNode.Create;
Node.Key:=cBase64[Random(cBase64Len)+1];
// ShowMessage('Button1: Begin'+IntToStr(i)+' '+Node.Key);
Tree.Add(Node);
DrawCount:=(DrawCount+1) mod 2;
Image:=TImage(FindComponent('Image'+IntToStr(DrawCount+1)));
// Image.Canvas.FillRect(Image.ClientRect);
// Tree.DrawTreeNode(Image.Canvas);
// ShowMessage('Button1: End'+IntToStr(i));
end;
T2:=Now;
ShowMessage(IntToStr(Round((t2-t1)*24*3600*1000)));
end;
担心random产生不同的结果,我自己写了一个随机数发生函数,保证DELPHI和FREEPASCAL都产生相同的树。
运行结果是:
DELPHI耗时234ms
Freepascal耗时141ms
(2)平衡二叉树的释放和创建
把上面的代码再执行一篇,相当于把上次的创建的树释放,然后重新创建一遍
第二次运行的是
DELPHI耗时328ms
Freepascal耗时187ms
(3)平衡二叉树的查找
var
s:string;
i:Integer;
T1,T2:TDateTime;
begin
T1:=Now;
for i:=1 to 1000*1000 do
begin
s:=cBase64[Random(cBase64Len)+1];
Tree.Find(s);
end;
T2:=Now;
ShowMessage(IntToStr(Round((t2-t1)*24*3600*1000)));
end;
DELPHI耗时218ms
Freepascal耗时141ms
(4)数学运算
var
s:string;
i:Integer;
T1,T2:TDateTime;
begin
T1:=Now;
for i:=1 to 1000*1000 do
begin
RandSeed:=round(math.power(10.5,3.2)+log10(1000*25*123)+sqrt(22*55)+math.sinh(1.2)*100)*100;
// s:=cBase64[Random(cBase64Len)+1];
// Tree.Find(s);
end;
T2:=Now;
ShowMessage(IntToStr(Round((t2-t1)*24*3600*1000)));
end;
DELPHI耗时235ms
Freepascal耗时218ms
(5)在画布上显示
var
i:Integer;
Node:TAVLTreeNode;
Image:TImage;
T1,T2:TDateTime;
begin
T1:=Now;
Tree.Clear;
RandSeed:=1;
DrawCount:=1;
for i:=1 to 200 do
begin
DrawCount:=(DrawCount+1) mod 2;
Image:=TImage(FindComponent('Image'+IntToStr(DrawCount+1)));
Image.Canvas.FillRect(Image.ClientRect);
Tree.DrawTreeNode(Image.Canvas);
Node:=TAVLTreeNode.Create;
Node.Key:=cBase64[Random(cBase64Len)+1];
// ShowMessage('Button1: Begin'+IntToStr(i)+' '+Node.Key);
Tree.Add(Node);
DrawCount:=(DrawCount+1) mod 2;
Image:=TImage(FindComponent('Image'+IntToStr(DrawCount+1)));
Image.Canvas.FillRect(Image.ClientRect);
Tree.DrawTreeNode(Image.Canvas);
// ShowMessage('Button1: End'+IntToStr(i));
end;
T2:=Now;
ShowMessage(IntToStr(Round((t2-t1)*24*3600*1000)));
end;
DELPHI耗时312ms
Lazarus耗时688ms
以上使用的DELPHI版本是 Lite Edition v7.3.4.1(Build8.1),FreePascal版本是2.6
总结:Freepascal在编译效果上基本上不输DELPHI,并且还强不少,并且Freepascal已经64位很长时间了,特别是在多种硬件平台和多种操作系统上都能编译运行。不过DELPHI7在画布上的显示速度明显超过Lazarus,这可能是因为Lazarus支持多种显示平台(win32、gtk、gtk2、carbon、qt、wince、fpgui、cocoa、android),多包了一层。lanzarus上的基本控件和DELPHI相比,有多有少。可以说lazarus可以进入实用阶段了。
以后有一部分程序可能会考虑用Lanzarus进行开发。有可能会和DELPHI混用。至少服务器肯定考虑用Freepascal了,因为Freepascal原生提供了比DELPHI原生提供多得多的大量的函数和组件(包括我上面使用的平衡二叉树就是一个例子,其它还有链表,杂凑、加密、压缩、CGI等),并且写服务器软件,有关DELPHI代码转到Freepascal代码比较容易。DELPHI上大量的第三方比较好的报表和显示控件要转到Lazarus还是不太容易,如果不考虑第三方控件,Lazarus已经完全可以替换Delphi了,但这些优秀的第三方显示和报表控件还是很难割舍的。