我需要s在程序中经常读取字符串的长度.我设置了s一次字符串,所以我可以在变量(NoOfChars)中记住它的大小,如下所示:
type
MyClass= class
Public
s: string;
NoOfchars: integer;
end;
procedure MyClass.SetS(const MyString: String);
begin
s:= MyString;
NoOfchars := Length(s); // <-- store it once, read it often
end;
Run Code Online (Sandbox Code Playgroud)
我想我读到的地方Length(s)和读取常量一样快,因为它只访问存储在字符串前面"hidden"字段中的字符串的长度.这很有意义,但由于我们没有源代码,我们只能猜测.也许还有其他涉及的计算?
那么,我应该使用Length(s)还是应该记住变量中的长度?
你有源代码.它在System单元中.
function _UStrLen(const S: UnicodeString): Integer;
begin
Result := Longint(S);
if Result <> 0 then // PStrRec should be used here, but
Result := PLongint(Result - 4)^; // a private symbol can't be inlined
end;
Run Code Online (Sandbox Code Playgroud)
这个辅助函数被标记为内联,实际上编译器会内联它.这个程序:
{$APPTYPE CONSOLE}
var
i: Integer;
s: string;
begin
i := Length(s);
Writeln(i);
end.
Run Code Online (Sandbox Code Playgroud)
编译如下:
.... Project1.dpr.10: i := Length(s); 004060E3 A19CAB4000 mov eax,[$0040ab9c] // $0040ab9c holds the variable s 004060E8 85C0 test eax,eax // test for nil 004060EA 7405 jz $004060f1 004060EC 83E804 sub eax,$04 // offset to length 004060EF 8B00 mov eax,[eax] // read length into eax 004060F1 8BD8 mov ebx,eax // compiler optimises i into ebx ....
代码非常简单.检查字符串变量是否为nil.如果是这样,答案就是零.否则,从字符串的适当偏移量读取长度.
这当然是一个非常快速的功能.但是,调用它的速度并不快Length,因为它是从本地变量读取的.实际上,编译器可以很好地将局部变量优化为寄存器.
因此,如果性能很重要,读入局部变量可以提高性能.但是,您必须计算现实世界的代码,以了解性能差异是否真正重要.
我个人倾向于将字符串长度存储在局部变量中,因为我需要不止一次地引用长度.如果我每次调用函数时都知道值相同,则可以通过将值存储在本地来表达.
FWIW您可以通过简单的测试轻松地了解变量的使用速度.当然,这并不会测试您的生产代码中的所有情况和可能性,但您会得到一个粗略的估计.
program Project1;
{$APPTYPE CONSOLE}
uses
Diagnostics;
var
sw: TStopwatch;
s: string;
len, i, x: Integer;
begin
s := 'somestring';
len := Length(s);
sw := TStopwatch.StartNew;
for i := 0 to MaxInt do
begin
x := len;
if x = 0 then
end;
Writeln('using variable: ', sw.ElapsedMilliseconds);
sw := TStopwatch.StartNew;
for i := 0 to MaxInt do
begin
x := Length(s);
if x = 0 then
end;
Writeln('using Length(s): ', sw.ElapsedMilliseconds);
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
在VM中,我得到这样的数字(发布配置):
using variable: 587
using Length(s): 1255
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
549 次 |
| 最近记录: |