是少使用短字符串为妙。
避免使用copy函数这也和滥用内存管理有关。一个典型的情形如下:
if copy(s1,23,64)=copy(s2,15,64) then ……
这样导致分配了两块临时内存,因而降低了效率。应当替换为如下代码:
i:=0;
f:=false;
repeat
f:=s1[i+23]<>s2[i+15];
inc(i);
until f or (i>63);
if not f then ……
同样的,如下语句就显得相当低效:
s:=copy(s,1,length(s)-10);
应改为
delete(s,length(s)-10,10);
顺便提一句,在连接字符串时,s:=s1+s2;简单而有效;但在delphi2下则s:=format([%s%s],s1,s2);可能稍快些。
总是使用长字符串,必要时转换为pchar先看看AnsiString的定义:
在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] 替换为如下代码: 这样导致分配了两块临时内存,因而降低了效率。应当替换为如下代码: 同样的,如下语句就
显得相当低效: 应改为 顺便提一句,在连接字符串时,s:=s1+s2;简单而有效;但在delphi2下则s:=format([%s%s],s1,s2);可能稍快些。
type
AnsiString = packed record
allocsiz: longint; //动态分配大小
refcnt: longint; //引用计数
Length: longint; //实际长度
ChrArr:array[1..allocsiz-6]of char; //字节序列
end;
其中astring[1]将返回astring.chrarr[1]的内容。很多人认为ansistring是天生低效的。其实这在很大程度上是由代码编写不良、内存管理乱用和缺乏支持的函数所致。如上所述,一旦被动态分配了一块内存,长字符串就成了一个线性的字节序列,并无所谓的效率问题。当然,若有更多有效的函数支持那就更好了。说到ansistring到pchar的转换,本质上有三个办法:
1.p:=@s[1];这会引发uniquestring调用。
2.p:=pchar (s);这会先检查s是否为空,若是,则返回nil,否则即返回s[1]的地址。
3.p:=pointer(s);这不会引发任何隐含调用,因而是在确定s非空情况下的最佳选择。
整数代码优化
尽量使用32位变量在32 位代码中32 位变量是默认处理格式16位变量 word shortint widechar 的运算会令处理器临时切换为 16位处理模式因而需要双倍的处理时间相较之下8位变量byte char 只要不与其它混用却不会太慢如果实在需要多次使用一个8或16位变量可以考虑把它临时转换成32 位变量这只需要一步赋值ADWord:=Aword;
避免使用子界类型Pascal语言的一大优势便是其丰富的数据类型Delphi之 Object Pascal继承了这一传统枚举和子界类型即属此类但不幸的是他们会为优化带来麻烦因为它们的占用的字节数取决于其子界的大小比如一个元素数不超过256个的枚举类型会占用1 个字节而例如MyYear=1900..2000则会占用两个字节而如前文所述16位变量是很慢的
简化表达式过于复杂的表达式会妨碍编译器的自动优化这时可以考虑引入临时变量来简化表达式这样可以优化更重要的是提高了代码的可读性
不再畏惧乘法PII出现以前乘法运算是相当费时的以至于当时的经典优化方法便是把一类特殊的乘法转变为移位运算和加法而今在作为标准配置的PII上乘法和多数其它运算一样只需要一个