Něco ohledně uvolňování řetezců

vložil Radek Červinka 18. listopadu 2011 23:03

Jen pro zajímavost pro začátečníky malé zamyšlení o řetezcích, Exception.CreateFmt a podobných funkcích.

Mějme následující kód:

    1program Project1;
    2
    3{$APPTYPE CONSOLE}
    4
    5uses
    6  SysUtils;
    7
    8  procedure m1(i:Integer);
    9  begin
   10    if i <> 1 then
   11      raise Exception.Create(Format('Error Message:%d', [i]));
   12  end;
   13  procedure m2(i:Integer);
   14  begin
   15    if i <> 1 then
   16      raise Exception.CreateFmt('Error Message:%d', [i]);
   17  end;
   18  procedure m3(i:Integer);
   19  begin
   20    if i <> 1 then
   21      raise Exception.Create('Error Message:'+ IntToStr(i));
   22  end;
   23
   24begin
   25  try
   26    m1(1);
   27    m2(1);
   28    m3(1);
   29    readln;
   30  except
   31    on E: Exception do
   32      Writeln(E.ClassName, ': ', E.Message);
   33  end;
   34end.

V případě uvedených volání sice nedojde k výjimce, ale otázkou je co je i tak nejefektivnější a proč?

Kompilátor musí zaručit uvolňování dynamických struktur jako jsou řetězce a různá pole na konci bloku kódu (tj. procedury). Podívejme se na ukázkové příklady:

V prvním případě je pro parametr výjimky volána funkce Format a výsledný řetězec je předán do konstruktoru. V druhém případě jsou parametry předány do jiného konstruktoru a v rámci této funkce není prováděno žádné jiné volání. Třetí případ potencionálně volá IntToStr a spojuje řetězce.

Nejméně efektivní je poslední volání, protože kompilátor vygeneruje interní sekci finally, která provede uvolnění potencionálních řetězců (parametry Exception.Create). Pokud se podíváme do přeloženého kódu uvidíme volání @UStrArrayClr. V případě, že nedojde k výjimce je toto volání provedeno nejkratší možnou cestou jelikož žádné řetězce nejsou, ale přesto je provedeno.

Pokud se podíváme na první příklad (m1), tak uvidíme podobnou situaci, jen je voláno @UStrClr, které uvolní jediný potencionální dočasný řetězec, který je výsledkem volání Format. Pokud nedošlo k výjimce, je z funkce @UStrClr vyskočeno hned na začátku.

No a nakonec tu máme příklad m2 - zde se žádný dočasný řetězec nevyskytuje, takže se žádný ani neuvolňuje, parametry se předávají přímo do volané funkce. Výsledkem je, že není generována žádná sekce "finally" a ani žádné uvolňování.

Co z toho plyne? Delphi (a asi i další vyšší jazyky) kouzlí a je třeba aspoň trochu chápat jak to asi funguje. Výsledkem může pak být jedině lepší kód.


Nabízíme Delphi školení a konzultace na různá témata, primárně ve Vaší firmě.

Tagy: , ,

Praxe

Komentáře

19.11.2011 11:37:13 #

<z>

ASM opravdu vubec nerozumim, tak jsem jen zkontroloval, ze ten druhy kod je opravdu nejkratsi :D

jen by me zajimalo, proc je takovy rozdil mezi temito 2 funkcemi
Exception.Create(Format('Error Message:%d', [i]));
Exception.CreateFmt('Error Message:%d', [i]);
kdyz CreateFmt ten samy Format vola, akorat uvnitr ... stejne se tam nekde ten retezec dal musi uvolnit ...

nebo to je tak, ze tam vznikl "nadbytecny" retezec?

<z>

19.11.2011 11:42:40 #

Radekc

Ano - ale v tom to je, ten druhý konstruktor sice také volá CreateFmt, ale volá ho až v jiném bloku kódu. Tj. pokud nedošlo k výjimce, tento druhý blok kódu se nevolá a tím pádem se nic neuvolňuje a tím ušetříme.

Prostě v případě výjimky to vyjde zhruba na stejno - ale v ostatních případech (a těch může být většina) ušetříme.

Radekc

20.11.2011 11:26:38 #

<z>

asi se na to budu muset podivat ... vim o nejaky prasarne s Exception v mym programu uz dyl, ze to tam neco neuvolnuje, ale sem si rikal, ze nakej bajt nehraje roli :D

<z>

Komentování ukončeno

Naše nabídka

Partial English version.

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy nebo burzy práce).

Pokud chcete podpořit tento server libovolnou částkou, můžete použít PayPal. Moc děkuji.

Delphi Certified Developer

O Delphi.cz

Delphi je jediný moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64 , Mac OSX a na iPhone a Android (s výhledem na další platformy díky FireMonkey) na současném trhu (včetně Windows 8.1).

V současnosti je světová komunita přes dva miliónů vývojářů.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Anketa

Poslední komentáře

Comment RSS