You do have the source code. It's in the System
unit.
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;
This helper function is marked as inline and indeed the compiler does inline it. This program:
{$APPTYPE CONSOLE}
var
i: Integer;
s: string;
begin
i := Length(s);
Writeln(i);
end.
is compiled to the following:
....
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
....
The code is pretty simple. The string variable is checked for being nil
. If so the answer is zero. Otherwise the length is read from the appropriate offset from the string.
This is certainly a pretty quick function. However, it won't be as quick to call Length
, even inlined as it is, as it is to read from a local variable. Indeed the compiler may well optimise a local variable into a register.
So if performance matters, reading into a local variable could improve performance. But you must time the real world code to know whether or not the performance difference actually matters.
Personally I tend to store string length in a local variable for reasons of readability if I need to refer to the length more than once. If I know the value is the same every time I call the function, it is clear to express that by storing the value in a local.