Original in Russian: http://programmingmindstream.blogspot.ru/2015/09/1165.html
I’ve profiled my scripts for efficiency (the problem roots in here - http://programmingmindstream.blogspot.ru/2015/09/1164-aqtime.html (in Russian)) and was surprised (again) to find out that (often) throwing the exception in business logic causes multiple loss in efficiency.
For example, the following code:
works many times slower that the analogue:
Why is it so?
The reason is that actually BREAK is organized as follows:
https://bitbucket.org/lulinalex/mindstream/src/7deb4ed1ebc5a138c2a90cc69f14bed0847b09a1/Examples/1165/BasicsPack.pas?at=B284&fileviewer=file-view-default
Basic time is “chewed” by object creation/deletion which is actually “rather costly”.
Here is the assembly code:
That is why I used to do my own object cach.
Here is an example:
https://bitbucket.org/lulinalex/mindstream/src/7deb4ed1ebc5a138c2a90cc69f14bed0847b09a1/Examples/1165/l3UnknownPrim.imp.pas?at=B284&fileviewer=file-view-default
In this case I made exceptions as singletons and used them in the following way:
In some degree, it solved the issue of efficiency.
Sure, this is all about “scripts”.
Indeed, I have found it at large working data sizes like the large model project (dozens of thousands classes and about 12-15 millions lines of code).
One would think Delphi developer does not care about it.
I just want to stress that “throwing exceptions” is a “costly” trick. Unnecessary use of exceptions in business logic (I have seen people doing so) as a “special function result” inevitably leads to efficiency loss.
It is so when exceptions are thrown relatively often compared to the “usual code”.
I would also like to write about ARC and exceptions but I’d rather won’t.
I do NOT think you will understand me right. ARC is mainstream, after all.
Though, as judged by the code, exceptions are ALSO exposed to ARC.
However, it seems the Embarcadero developers have not faced these problems yet.
Thus, let’s consider these thoughts as “my personal phantom pain”.
I’ve profiled my scripts for efficiency (the problem roots in here - http://programmingmindstream.blogspot.ru/2015/09/1164-aqtime.html (in Russian)) and was surprised (again) to find out that (often) throwing the exception in business logic causes multiple loss in efficiency.
For example, the following code:
ARRAY FUNCTION LIST
OBJECT IN anObject
^ IN aFunctor
OBJECT VAR l_Element
l_Element := anObject
Result := [
while true
begin
l_Element := ( l_Element aFunctor DO )
if ( l_Element pop:object:IsNil ) then
BREAK
l_Element
end
]
; // LIST
works many times slower that the analogue:
ARRAY FUNCTION LIST
OBJECT IN anObject
^ IN aFunctor
OBJECT VAR l_Element
l_Element := anObject
BOOLEAN VAR l_NeedDo
l_NeedDo := true
Result := [
while l_NeedDo
begin
l_Element := ( l_Element aFunctor DO )
if ( l_Element pop:object:IsNil ) then
begin
l_NeedDo := false
end
else
l_Element
end
]
; // LIST
Why is it so?
The reason is that actually BREAK is organized as follows:
https://bitbucket.org/lulinalex/mindstream/src/7deb4ed1ebc5a138c2a90cc69f14bed0847b09a1/Examples/1165/BasicsPack.pas?at=B284&fileviewer=file-view-default
procedure TkwBREAK.DoDoIt(const aCtx: TtfwContext);
//#UC START# *4DAEEDE10285_9FA400CD8713_var*
//#UC END# *4DAEEDE10285_9FA400CD8713_var*
begin
//#UC START# *4DAEEDE10285_9FA400CD8713_impl*
raise EtfwBreak.Create('Loop exit');
//#UC END# *4DAEEDE10285_9FA400CD8713_impl*
end;//TkwBREAK.DoDoIt
Basic time is “chewed” by object creation/deletion which is actually “rather costly”.
Here is the assembly code:
Here is an example:
https://bitbucket.org/lulinalex/mindstream/src/7deb4ed1ebc5a138c2a90cc69f14bed0847b09a1/Examples/1165/l3UnknownPrim.imp.pas?at=B284&fileviewer=file-view-default
class function _l3UnknownPrim_.NewInstance: TObject;
//override;
{* - memory allocation function for object’s instance; it is overridden to check the memory for the objects. }
{$IfDef _UnknownNeedL3}
var
l_System : Tl3System;
{$EndIf _UnknownNeedL3}
begin
{$IfDef _UnknownNeedL3}
l_System := Tl3System(g_l3System);
if (l_System = nil) then
begin
if not l3MemUtilsDown{l3SystemDown} then
begin
l_System := l3System;
// if (l_System <> nil) then
// l_System.Stack2Log('Possible oddness NewInstance/FreeInatance');
end;//not l3SystemDown
end;//l_System = nil
Assert((l_System <> nil) OR not Cacheable);
if (l_System <> nil) AND l_System.CanCache AND Cacheable then
begin
Result := GetFromCache;
if (Result <> nil) then
begin
_l3UnknownPrim_(Result).InitAfterAlloc;
Exit;
end;//Result <> nil
end;{l_System.CanCache}
{$EndIf _UnknownNeedL3}
Result := AllocInstanceMem;
_l3UnknownPrim_(Result).Use;
_l3UnknownPrim_(Result).InitAfterAlloc;
{$IfDef _UnknownNeedL3}
{$IfDef l3TraceObjects}
if (l_System <> nil) then
l_System.RegisterObject(Result, Cacheable);
{$EndIf l3TraceObjects}
{$EndIf _UnknownNeedL3}
end;
In this case I made exceptions as singletons and used them in the following way:
procedure TkwBREAK.DoDoIt(const aCtx: TtfwContext); //#UC START# *4DAEEDE10285_9FA400CD8713_var* //#UC END# *4DAEEDE10285_9FA400CD8713_var* begin //#UC START# *4DAEEDE10285_9FA400CD8713_impl* raise EtfwBreak.Instance; //#UC END# *4DAEEDE10285_9FA400CD8713_impl* end;//TkwBREAK.DoDoIt
In some degree, it solved the issue of efficiency.
Sure, this is all about “scripts”.
Indeed, I have found it at large working data sizes like the large model project (dozens of thousands classes and about 12-15 millions lines of code).
One would think Delphi developer does not care about it.
I just want to stress that “throwing exceptions” is a “costly” trick. Unnecessary use of exceptions in business logic (I have seen people doing so) as a “special function result” inevitably leads to efficiency loss.
It is so when exceptions are thrown relatively often compared to the “usual code”.
I would also like to write about ARC and exceptions but I’d rather won’t.
I do NOT think you will understand me right. ARC is mainstream, after all.
Though, as judged by the code, exceptions are ALSO exposed to ARC.
However, it seems the Embarcadero developers have not faced these problems yet.
Thus, let’s consider these thoughts as “my personal phantom pain”.

Комментариев нет:
Отправить комментарий