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:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

  procedure m1(i:Integer);
  begin
    if i <> 1 then
      raise Exception.Create(Format('Error Message:%d', [i]));
  end;
  procedure m2(i:Integer);
  begin
    if i <> 1 then
      raise Exception.CreateFmt('Error Message:%d', [i]);
  end;
  procedure m3(i:Integer);
  begin
    if i <> 1 then
      raise Exception.Create('Error Message:'+ IntToStr(i));
  end;

begin
  try
    m1(1);
    m2(1);
    m3(1);
    readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

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.

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

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).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

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.

Poslední komentáře

Comment RSS

Dle měsíců