Dostęp za pomocą . i -> - który szybszy?

0

Heja Bracia

Tak mnie naszło pytanie-czy jest różnica w szybkości przy dostępie do składnika klasy podczas odwołania się doń poprzez operator . a operator -> ?
Nie wiem na pewno,ale wydaje mi się,że przy . jest odwołanie pod bezpośredni adres w pamięci,natomiast -> oznacza offset od początku klasy i adres składnika dopiero z tego jest wyliczany.

Jak to jest w istocie?

0

Dla:

void PointerTest(TestClass* testClass)
{
	printf("to jest wartosc przez wskaznik %i\n", testClass->value);
}

void ReferenceTest(TestClass& testClass)
{
	printf("to jest wartosc przez referencje %i\n", testClass.value);
}

Kompilator Microsoftu wygenerował zupełnie identyczne assembly i dla podania argumentu i ciał funkcji. Nie znam się na optymalizacjach kompilatorów, ale nie ma chyba co się głowić nad takimi pierdołami ;). Z włączonymi optymalizacjami, 40 linijkowy program w C++ skrócił do 11 linijek assembly (!), wywalił klasy, wywołania metod, argumenty ;P.

0

UO,sroogo z tym wywalaniem :P

No nic,dzięki Rev

2

Kompilator Microsoftu wygenerował zupełnie identyczne assembly i dla podania argumentu i ciał funkcji.
to zrozumiałe, bo referencja jest w rzeczywistości niejawnym wskaźnikiem, więc kropka w drugim przykładzie jest automatycznie zamieniana na dereferencję (czyli ->).
żeby porównać kod, zrób przykład bez wskaźnika i bez referencji.
tak, odwołanie przez kropkę przy obiekcie powinno być szybsze od odwołania przez strzałkę przy wskaźniku lub kropkę przy referencji.

0

Używanie wskaźników czy referencji jest z reguły tak samo szybkie (ponieważ zostanie zoptymalizowane tak czy siak) jak używanie adresów względnych czy bezwzględnych o stałym przesunięciu z wyjątkiem przypadków w których robimy mieszane zapisy i odczyty używając wielu wskaźników.

Dla przykładu następujący kod jest problemowy:

void* wskaźnik1 = blabla;
void* wskaźnik2 = blabla;
int a = *wskaźnik1;
wskaźnik2* = 5;
int b = *wskaźnik1;

Kompilator nie wie czy wskaźnik1 == wskaźnik2, więc w ostatniej linii musi zrobić ponowny odczyt z pamięci nawet jeżeli wartość a jest w rejestrze. W C99 jest słówko kluczowe restrict sugerujące kompilatorowi, aby olewał aliasing i traktował wskaźniki jako wskazujące na różne obszary pamięci.

1

Odwołanie się do elementu przez kropkę jest szybsze bo to po prostu - jeśli element jest na stosie - odwołanie do znanej w momencie kompilacji lokacji w pamięci.

Przez wskaźnik (referencję) jest gorzej, bo mamy dwa kroki - 1) pobierz wartość wskaźnika (referencji) ze znanego podczas kompilacji miejsca pamięci do rejestru i 2) pobierz wartość wskazywaną przez rejestr do docelowego miejsca/rejestru.

Z drugiej strony, przekazywanie wskaźnika (referencji) jest szybsze od przekazywania struktury z tego prostego powodu że wskaźnik zawsze zajmuje 4 bajty (w 32 bitowym programie) a struktura niekoniecznie... Ogólna zasada mogłaby brzmieć - jeśli przekazujesz coś większego od 8 bajtów zastanów się nad przekazaniem przez referencję.

Z trzeciej strony, ja bym się zupełnie tym nie przejmował i zostawił to kompilatorowi.
Weź na przykład pod uwagę że kod

my_struc *a = foo();
b = a->sb;
c = a->sc;

zostanie rozwinięty prawdopodobnie w

my_struc *a = foo();
my_struc av = *a;
b = av.sb;
c = av.sc;

oczywiście przy użyciu rejestrów procesora a nie zmiennych na stosie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1