When SetLength(AnyKindOfStringType, 0) is replaced with AnyKindOfStringType := '' the compiler produces better code because it avoids calling the SetLength procedure.
is that actually true?
then it calls fpc_AnsiStr_Assign
I don't know why but I remember that
the first time a value was assigned to a string variable in a routine and that value was an empty string, the compiler would have completely avoided the call to fpc_stringtype_assign. Instead of calling the assign routine, something like an inlined code was executed. You know, like it does with shortstrings(change TestString to shortstring in the example below and notice there's a single instruction produced instead of going into
fpc_shortstr_setlength). With the latest fpc development version I see the assign routine too.

program Project1;
type
TestString = ansistring;
//shortstring;
//unicodestring;
procedure foo(var param:TestString);
begin
param:='';
end;
procedure bar(var param:TestString);
begin
setlength(param, 0);
end;
var
L: TestString;
begin
L:='';
setlength(L, 0);
foo(L);
bar(L);
writeln(L);
end.
Anyway, even with this unpleasant surprise, unlike
fpc_ansistr_setlength,
fpc_ansistr_assign doesn't additionally call
fpc_ansistr_decr_ref.
This is the code executed.
fpc_ansistr_assign
000000000040ADB0 53 push rbx
000000000040ADB1 4154 push r12
000000000040ADB3 50 push rax
000000000040ADB4 4889FB mov rbx,rdi
000000000040ADB7 4989F4 mov r12,rsi
000000000040ADBA 483B37 cmp rsi,[rdi]
000000000040ADBD 7422 jz +$22 # $000000000040ADE1 fpc_ansistr_assign+49
...
000000000040ADE1 59 pop rcx
000000000040ADE2 415C pop r12
000000000040ADE4 5B pop rbx
000000000040ADE5 C3 ret
vs.
fpc_ansistr_setlength
000000000040BF10 53 push rbx
000000000040BF11 4154 push r12
000000000040BF13 4155 push r13
000000000040BF15 488D6424F0 lea rsp,[rsp-$10]
000000000040BF1A 4889FB mov rbx,rdi
000000000040BF1D 4989F4 mov r12,rsi
000000000040BF20 664189D5 mov r13w,dx
000000000040BF24 4885F6 test rsi,rsi
000000000040BF27 0F8E0B010000 jle +$0000010B # $000000000040C038 fpc_ansistr_setlength+296
...
000000000040C038 4889DF mov rdi,rbx
000000000040C03B E810EDFFFF call -$000012F0 # $000000000040AD50 fpc_ansistr_decr_ref
000000000040C040 488D642410 lea rsp,[rsp+$10]
000000000040C045 415D pop r13
000000000040C047 415C pop r12
000000000040C049 5B pop rbx
000000000040C04A C3 ret
fpc_ansistr_decr_ref
000000000040AD50 53 push rbx
000000000040AD51 48833F00 cmp qword ptr [rdi],$00
000000000040AD55 7429 jz +$29 # $000000000040AD80 fpc_ansistr_decr_ref+48
...
000000000040AD80 5B pop rbx
000000000040AD81 C3 ret
By using just a few instructions instead, can't FPC replace the call to assign when the first assignment to a variable is an empty string!? Either I'm confusing things, either there was a time when FPC did it. Overall, with those few instructions instead of the call to SetLength, the improvement is welcomed, especially because many developers have the tendency to assign empty string values to variables and function results at the beginning of the routines. They use these assignments as default values, or as workarounds to avoid warnings when using SetLength later in code.
EDIT: Maybe the assign routine was inlined at the time I've done tests in the past and now it's no longer inlined.