Předpokládám, že je to všeobecně známo jelikož se to píše všude, ale přesto. V unicode verzích Delphi (tj. 2009 a 2010) je pro lepší kompatibilitu s C++ Builderem implementována možnost lepší detekce správnosti hodnoty typu string. Rovnou říkám, že se jednalo o přechodné období, protože v budoucích Delphi to již nebude, jak napsal Allen Bauer na svém blogu.
Připomínám, že přechod na unicode je největší skok v historii Delphi, podobné je snad jen Delphi 1 (16 bit) -> Delphi 2 (32 bit).
Ale zpět. Tuto kontrolu klidně můžete vypnout (což už určitě máte) v případě, že používáte jen Delphi a tímto krokem získáte určité malé zrychlení.
Všimněte si dvou voleb: inline kodu a toho stringchecks.
Výsledky této volby si ukážeme v praxi. Pro jednoduchost si zopakujeme, že volba optimalizace za pomoci inline kódu je ekvivalentem {$INLINE xx} a řízení kontroly řetězců je {$STRINGCHECKS xx}. Defaultním nastavením je {$STRINGCHECKS ON} a {$INLINE ON} (tj. oboje zapnuté).
Mějme tedy tento program (ekvivalent originálního nastavení):
program Project1;
{$APPTYPE CONSOLE}
{$STRINGCHECKS ON} // ekvivalent nastavení v options
{$INLINE ON} // ekvivalent nastavení v options
var
s: string;
i: Integer;
begin
s:= 'delphi.cz';
i := Length(s);
writeln(i);
end.
V assembleru je to pak takto: všimněte si InternalUStrFromLStr, což je zbytek po inline funkce pro kontrolu stringu (viz poslední ukázka).
Project1.dpr.9: s:= 'delphi.cz';
004050D7 B8389B4000 mov eax,$00409b38
004050DC BA54514000 mov edx,$00405154
004050E1 E81EEFFFFF call @UStrAsg
Project1.dpr.10: i := Length(s);
004050E6 A1389B4000 mov eax,[$00409b38]
004050EB 85C0 test eax,eax
004050ED 741B jz $0040510a
004050EF 8BD0 mov edx,eax
004050F1 83EA0A sub edx,$0a
004050F4 66833A02 cmp word ptr [edx],$02
004050F8 7410 jz $0040510a
004050FA B8389B4000 mov eax,$00409b38
004050FF 8B15389B4000 mov edx,[$00409b38]
00405105 E8BAEEFFFF call @InternalUStrFromLStr
0040510A 85C0 test eax,eax
0040510C 7405 jz $00405113
0040510E 83E804 sub eax,$04
00405111 8B00 mov eax,[eax]
00405113 8BD8 mov ebx,eax
Project1.dpr.11: writeln(i);
00405115 A1AC674000 mov eax,[$004067ac]
Nyní kontrolu vypneme - ideální stav, doporučeno.
program Project1;
{$APPTYPE CONSOLE}
{$STRINGCHECKS OFF} // ekvivalent nastavení v options
{$INLINE ON} // ekvivalent nastavení v options
var
s: string;
i: Integer;
begin
s:= 'delphi.cz';
i := Length(s);
writeln(i);
end.
Výsledný kód je mnohem optimálnější, žádné zbytečné volání:
Project1.dpr.10: s:= 'delphi.cz';
004050D7 B8389B4000 mov eax,$00409b38
004050DC BA34514000 mov edx,$00405134
004050E1 E80EEFFFFF call @UStrAsg
Project1.dpr.11: i := Length(s);
004050E6 A1389B4000 mov eax,[$00409b38]
004050EB 85C0 test eax,eax
004050ED 7405 jz $004050f4
004050EF 83E804 sub eax,$04
004050F2 8B00 mov eax,[eax]
004050F4 8BD8 mov ebx,eax
Project1.dpr.12: writeln(i);
004050F6 A1AC674000 mov eax,[$004067ac]
004050FB 8BD3 mov edx,ebx
No a nakonec nejhorší varianta - zapnutá kontrola řetězců a vypnuté inline optimalizace.
program Project1;
{$APPTYPE CONSOLE}
{$STRINGCHECKS ON} // ekvivalent nastavení v options
{$INLINE OFF} // ekvivalent nastavení v options
var
s: string;
i: Integer;
begin
s:= 'delphi.cz';
i := Length(s);
writeln(i);
end.
Výsledek obsahuje volání EnsureUnicodeString, což určitě není optimální.
Project1.dpr.11: s:= 'delphi.cz';
004050D7 B8389B4000 mov eax,$00409b38
004050DC BA34514000 mov edx,$00405134
004050E1 E83EEFFFFF call @UStrAsg
Project1.dpr.12: i := Length(s);
004050E6 B8389B4000 mov eax,$00409b38
004050EB E8E4EEFFFF call @EnsureUnicodeString
004050F0 E87FF0FFFF call @UStrLen
004050F5 8BD8 mov ebx,eax
Project1.dpr.13: writeln(i);
004050F7 A1AC674000 mov eax,[$004067ac]
004050FC 8BD3 mov edx,ebx
Vypnutím kontroly formátu řetězců tedy získáte malé zvýšení rychlosti a o trochu menší výslednou binárku. Stejně ale autoři měli udělat volbu primárně vypnutou.