wydajnosc: self i inne

0

Mam pare pytan dotyczacych wydajnosci. Albowiem pisze program i musze zdecydowac sie na pewne rozwiazania - a nie wiem na ktore.

Mam klasy:
TBrain -> TSlice -> TSlicePoints -> TLinks
Uwaga - to nie jest hierarchia klas (w sensie pochodzenia), wszystkie są class(TObject).
Ta hierarchia oznacza, ze obiekt klasy wyzszej w hierarchii zawiera TObjectList na ktorej sa obiekty klasy nizszej. A obiekt klasy nizszej zawiera pole Parent z odniesieniem do odpowiedniego obiektu klasy wyzszej.
Teraz pytania:

  1. Jesli z obiektu TLinks odwoluje sie do pola TBrain.costam, stosuje
self.Parent.Parent.Parent.costam

1a. czy self, ktore jest tu nadmiarowe, ale ulatwia pisanie ze wzgledu na CodeInsight (i jasnosc tekstu) obniza wydajnosc?

1b. czy taki wielokrotny Parent obniza wydajnosc? wydaje mi sie, ze powinien byc skompilowany na pojedyncze odniesienie, ale wolalbym byc pewien. W razie czego moge zrobic pola GrandParent i GrandGrandParent i wypelniac je w konstruktorach, ale mi sie nie chce

  1. do obiektow na TObjectList odwoluje sie np tak (np do listy TBrain.Slices:TObjectList):
(Brain.Slices[i] as TSlice).JakiesPoleTSlice

, czyli za kazdym razem rzutuje, bo nie chcialo mi sie pisac trzech klas pochodnych od TObjectList, w ktorych identyczne rzutowanie robilbym w metodach tych klas pochodnych. Wydaje mi sie, ze nie trace w ten sposob na wydajnosci - czy to prawda?

0

Ad. 1a Self nic nie zmienia. I tak konieczne jest odwolanie sie do VMT, a to mozna zrobic dopiero majac odpowiednie pole w obiekcie.
Ad. 1b Teoretycznie tak, poniewaz dynamicznie sa przyporzadkowywane kolejen "dzieci", wiec by otrzymac rodzica nalezy isc po lancuchu dynamicznym do gory, a to wymaga kilku operacji. Jednak w praktyce zysk wydajnosci bylby mnimalny. To jak roznica w wydajnosci pomiedzy metoda statyczna i virtualna... prawie jej nie ma.
Ad. 2 Glowy uciac sobie nie dam, ale raczej niewiele tracisz. Co prawda delphi posiada mechanizm RTTI i prawdopodobnie jest on wykorzystywany przy takim rzutowaniu (a na pewno jest przy is), ale nie ma innej mozliwosci zrobienia tego. Zawsze rzutujac w dol trzeba sie liczyc z tym, ze kompilator moze za nas zrobic czarna robote i jednak sprawdzic, czy oby na pewno to jest ta klasa.

0

W pewine sposób obniża wydajnośc... Bo robi sie kolejka wskazników, przez którą musisz przejśc. Na pewno grandparend i supergrandparent bedzie szybsze, ale coś za coś... Szybkość wzgledem rozmiaru danych.

Rzutowanie rozmiarowe (nie zachodzi fizyczna konwersja rozmieszczenia bitów w zmiennej - a nie wiem jak działa as) jest robione raz... podczas kompilacji i tylko do kompilacji ono służy... W czasie działania programu nie ma znaczenia, czy dany typ był rzutowany, czy nie... Po prostu jest to narzucenie kompilatorowi interpretacji zmiennej jako innego wygodniejejszego w danym momencie typu. Nie wiem jak działa as... jeśli to operator czasu rzeczywistego... to zawsze cos stracisz na konwersje, ale nie sądzę.

var a:integer;
longint(a)=-1; // bez sensu bo to to samo, ale jako przykład dobre

const nil=pointer(longint(0)); // lepsze

0

Dzieki wam

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.