[c++] wkaźnikowy zapis tablicy

0

Mam pytanie..
Czy to:

*(tab+i);

jest na prawdę szybszę (jeżeli tak to o ile)
od tego:

tab[i];

i czy jest odpowiednik tej notacji dla tablic wielowymiarowych??
W internecie ludzie mówią różnie..

0
sid90 napisał(a)

Mam pytanie..
Czy to:

*(tab+i);

jest na prawdę szybszę (jeżeli tak to o ile)
od tego:

tab[i];

Gcc stworzyl dluzszy troche kod dla *(tab+i) przy prostym tescie, ale to nie moze byc uznawane za wyznacznik tego, ktore jest szybsze dlatego tez nie wrzucam deadlistingu. Moim zdaniem oba odwolania powinny byc traktowane tak samo.

0

wiesz co to arytmetyka wskaźników?

   
 int b[][2] = { {2, 12}, {22, 32} };
 for( int i  = 0; i < 2; ++i )
     for( int j = 0; j < 2; ++j )
         cout << *(*(b+i)+j) << " ";

Jest szybsze ale tylko z tego powodu, że kompilator musi to sobie przetłumaczyć i tak na "wersję wskaźnikową", więc tylko to jest opóźnieniem, a co za tym idzie nie jest to na tyle istotna różnica aby się nią przejmować. Jeśli ktoś szuka optymalizacji w takich miejscach to znak, że trzeba zmienić algorytm, a nie zapis tablic (oczywiście nie mówię o tobie):]

0

Pytałem sie z ciekawości, bo przypomniało mi się, że kiedyś mój wykładowca tak mówił:)

0

Mi się zdaje, że jeżeli jest różnica to tylko i wyłącznie w czasie kompilacji a nie wykonania programu.

0
int main(){
 int t[100];
 int i=0;
 for(int aa=0; aa<1000; aa++)
  for(int a=0; a<10000; a++)
   for(i=0; i<100; i++)
     //t[i]=i;
     *(t+i)=i;
 return 0;
}

Bez optymalizacji zapis *(t+i) jest chyba o niewielki procent szybszy (może margines błędu spowodowanego obciążeniem, ale nie sądzę).

Przy optymalizacji -O2 dzieje się coś dziwnego: sposób t[i] wykonuje się w "trybie natychmiastowym" (0.003s), a *(t+i) ok. 0.8 sek.
Widocznie optymalizator zauważył że ten kod to bzdura i go pominął. W wygenerowanym assemblerze rzeczywiście jest o połowę mniej kodu dla t[i].

Dodałem na koniec printf("%d", t[0]), żeby optymalizator nie pominął tej pętli. Czasy są porównywalne. Może to dlatego, że wygenerowane kody assemblera są identyczne znak w znak?

Czyli jeżeli kompilujesz z -O2 to nie ma znaczenia który sposób wybierasz.

Testowane na Linuksie z GCC 4.4.3

//EDIT: chyba wiem czemu w jednym przypadku optymalizator uznał tą tablice i pętle za głupotę, a w drugim nie. W t[i] kompilator od razu wie że pewnej zmiennej przyporządkujemy jakąś wartość. Ale jej nie pobieramy w żaden sposób. kompilator od razu zna docelowy adres
Przy *(t+i) kompilator musi najpierw obliczyć adres dla LVALUE. Pobiera wskaźnik t i dodaje do niego i. I w ten sposób kompilator stwierdza, że tablica (wskaźnik) t jest jednak potrzebny, bo jego wartość jest pobierana

Tak mi się przynajmniej wydaje.

0

@Razi91 zauważ, że za każdym odpaleniem wyniki będą inne!
ale qrcze, sam widzę, że zapis tradycyjny jest jakby szybszy od wksaźnikowego..

aaa i jakbyś wyświetlał tak: *(t+i)=i; tak zadeklarowaną tablice: tab[100]
to by sie raczej wysypało.

0

I w ogóle widzę, że takie mierzenie kompilatorem jest raczej do d**y.. Kod mający złożoność n^2 wykonuję się tyle samo co przypisanie w pętli.. Nie wiem o co tu kaman.

0

Moje zdanie jest takie, że szamanizm ze wskaźnikami jest trudniejszy do opanowania przez kompilator. Zwykłe odwołania tablica[indeks] powinny być prostsze do ogarnięcia i zoptymalizowania.

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