首页 > 应用 > 编程开发 > 正文

Delphi代码优化教程

2024-07-15 02:01:38
字体:
来源:转载
供稿:网友

Delphi代码优化教程:

字符串优化
delphi有三种字符串类型:短字符串(string[n],n=1..255)存储区为静态分配,大小在编译时确定,这是继承于bp for dos的类型;字符数组(pchar)主要是为了兼容各类api,在bp7中已经出现,如今在delphi中更加应用广泛,其存储区可以用字符数组静态分配,也可用getmem手动分配;而长字符串(ansistring)是delphi独有的,其存储区在运行时动态分配,最灵活也最易被滥用。

不重复初始化delphi默认字符串类型AnsiString会自动初始化为空。如下代码:

delphi有三种字符串类型:短字符串(string[n],n=1..255)存储区为静态分配,大小在编译时确定,这是继承于bp for dos的类型;字符数组(pchar)主要是为了兼容各类api,在bp7中已经出现,如今在delphi中更加应用广泛,其存储区可以用字符数组静态分配,也可用getmem手动分配;而长字符串(ansistring)是delphi独有的,其存储区在运行时动态分配,最灵活也最易被滥用。

var s:string;
begin
s:="";
……
end;

s:="";就属多此一举。但是值得注意的是这对函数返回值result无效。而一般说来,用var实参传递比返回字符串值要更快一些。

使用SetLength预分配长字符串(AnsiString)动态分配内存是AnsiString的一大长项,但容易弄巧成拙,一个典型的例子如下:

s2:=" ";
for i:=2 to length(s1) do s2:=s2+s1[i];

且不说可用delete取代之,主要问题在于上例的循环中s2的内存区域被不停地重复分配,相当费时。一个简单有效的办法如下:

setlength(s2,length(s1)-1);
for i:=2 to length(s1) do s2[i-1]:=s1[i];

这样s2内存只会重新分配一次。

字符串与动态数组的线程安全(Thread Safety)在delphi 5以前动态数组与长字符串的操作这些非线程安全调用是由引用计数来处理其临界问题的,而自delphi5起就改为直接在一些临界指令前加lock指令前缀来避免这个问题。不幸的是这一修改的代价相当昂贵,因为在pentiumⅱ处理器中lock指令相当费时,大概要耗费额外的28个指令周期来完成这一操作,因而整体效率至少下降一半。解决这个问题的办法只有一个,那就是修改delphi rtl核心代码。在备份原文件后,将source/rtl/sys/system.pas中所有的lock替换为{lock},当然必须是整字替换。如此还未完全优化,下一步是将delphi4运行库中也有的xchg指令去掉,因为该指令有隐含的lock前缀,所以必须将system.pas内_lstrasg和_strlasg两个过程中的 xchg edx,[eax] 替换为如下代码:

mov ecx,[eax]
mov [eax],edx
mov edx,ecx

ok大功告成,编译一下,覆盖system.dcu即可。如此其执行效率将比delphi5提高6倍,比delphi4提高2倍。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表