Cześć,
Mam pytanie czy jeśli mam wskaźnik pokazujący na jakąś zmienną to czy wyłuskując z niej wartość ponoszę jakiś koszt czasowy? Czy ma to jakiś wpływ na wydajność aplikacji (nawet minimalny)? Czy może wyłuskanie jest wykonywane w procesie kompilacji i nie ma wpływu na wydajność aplikacji?
Z góry dziękuję za odpowiedź.
To zależy. Jeśli to byłaby zmienna na stosie to kompilator mógłby to zoptymalizowac. Jeśli zmienna jest na stercie (alokowana dynamicznie) to koszt jest.
Samo wyłuskanie to tylko formalność (o ile masz naprawdę wskaźnik).
Dzięki za info.
Ogólnie to mam tak, że w jednej klasie mam wskaźnik(1) do innego wskaźnika(2) do tablicy utworzonej dynamicznie. Niestety czasami wartość tego wskaźnika(1) się zmienia (pokazuje na inną tablicę).
W innej klasie mam natomiast wskaźnik(3), który pokazuje właśnie na ten wskaźnik(1) (by również odnosić się do tych samych zmiennych. Niestety dlatego, że czasami ten wskaźnik(1) zmienia się postanowiłem dać w tej drugiej klasie wskaźnik na wskaźnik - wówczas nie musiałbym przestawiać wskaźnika w dwóch klasach tylko w jednej.
Problem jest taki, że w tej drugiej klasie musiałbym już wykonywać operacje z wyłuskaniem a dlatego, że operacji będzie dużo to zacząłem się zastanawiać nad optymalizacją.
A tak przy okazji inne pytanie: czy w VS C++ muszę coś ustawić, by rzetelnie testować czas wykonywania różnych operacji?
Nie znam się za dobrze na tym. Chodzi mi o to, by program mi nie zapamiętywał wyników czy coś takiego. Tu chyba chodzi o pamięć podręczną (?)...
Pozdrawiam
W tym co opisujesz już nie jest samo wyłuskanie, tylko zapisywanie wartości wyłuskanego wskaźnika, a to już zajmuje czas.
dzięki za odpowiedź!
A czy mógłbym prosić jeszcze na ostatnie pytanie:
A tak przy okazji inne pytanie: czy w VS C++ muszę coś ustawić, by rzetelnie testować czas wykonywania różnych operacji?
Nie znam się za dobrze na tym. Chodzi mi o to, by program mi nie zapamiętywał wyników czy coś takiego. Tu chyba chodzi o pamięć podręczną (?)...
z góry dziękuję!
w asmie to wyłuskanie wartości pokazywanej przez wskaźnik lokalny może wyglądać np tak:
mov eax,[ebp - 8] ; kopiujemy sam adres do eax
mov ebx,[eax] ; teraz w ebx jest już wartość pokazywana przez wskaźnik
Kontynuując temat wydajności mam jeszcze jedno pytanie w temacie:
Mam klasę ze zmienną i funkcją typu:
class klasa
{
public:
double zmienna;
double funkcja(double*&, double*&);
};
double klasa::funkcja(double*& x, double*& y)
{
zmienna = 0.0;
//... jakieś obliczenia typu
for(int i=0; i<1000; i++)
zmienna += x[i]*y[i];
return zmienna;
}
Czy jeśli funkcja będzie zwracać referencję do zmiennej zamiast jej kopii j.w. czyli będzie typu double& funkcja(...) to czy będzie to wydajniejsze jak to co wyżej?
Wynik tej funkcji będzie przypisywany do zmiennej w innej klasie - ale to chyba nie istotne.
Z góry dziękuję za pomoc.
Ale to nie jest zwracanie lokalna funkcji!
To jest zmienna zadeklarowana w klasie.
Widzę, że brak chętnych do odpowiedzi ;-(
Postanowiłem zrobić testy samodzielnie. Zrobiłem następujące klasy:
class klasa1
{
public:
double zmienna;
double funkcja(double* x, double* y, int n, int i)
{
zmienna = 0.0;
for(int i=0; i<n; i++)
zmienna += x[i]+y[i] + i;
return zmienna;
}
};
class klasa2
{
public:
double zmienna;
double& funkcja(double* x, double* y, int n, int i)
{
zmienna = 0.0;
for(int i=0; i<n; i++)
zmienna += x[i]+y[i] + i;
return zmienna;
}
};
W mainie dałem taki kod:
int count = 100000000;
double* tabA = new double[count];
double* tabB = new double[count];
klasa1 k1;
klasa2 k2;
srand( time( NULL ) );
double* tab1 = new double[10];
double* tab2 = new double[10];
for(int i=0; i<10; i++)
{
tab1[i] = (double)rand()/RAND_MAX;
tab2[i] = (double)rand()/RAND_MAX;
}
clock_t start, koniec, roznica1, roznica2;
start = clock();
for(int i = 0; i<count; i++)
tabA[i] = k1.funkcja(tab1, tab2, 10, i);
koniec = clock();
roznica1 = koniec - start;
start = clock();
for(int i = 0; i<count; i++)
tabB[i] = k2.funkcja(tab1, tab2, 10, i);
koniec = clock();
roznica2 = koniec - start;
cout << "czas1 = " << roznica1/1000.0 << " s. " << endl;
cout << "czas2 = " << roznica2/1000.0 << " s. " << endl;
Wnioski:
Średnia z pierwszych 3 losowań było mniej więcej taka: roznica1 = 11.77, roznica2 = 11,28
Następnie zmieniłem miejscami wykonywanie operacji - najpierw zmierzyłem czas dla drugiej klasy potem dla pierwszej i wyniki są odwrotne.
roznica2 = 11.65, roznica1 = 11.34
Czyli kod, który się wykonywał wcześniej miał jakiej "obsunięcie". Czy może mi ktoś wyjaśnić dlaczego?
Wniosek jest taki, że referencja chyba minimalnie poprawiła wynik - w pierwszych 3 testach wypadła lepiej, w drugich 3 testach wypadła gorzej, ale lepiej niż druga klasa w pierwszych testach.
Raju, ale głupoty gadam. Po odwróceniu wykonywania operacji (najpierw druga klasa potem pierwsza) wyniki trochę się pogorszyły dla referencji (wykonywana pierwsza) i trochę polepszyły dla drugiej klasy. Jednak w obu przypadkach referencja okazała się lepsza ;-);
Jednak okazuje się, że referencja nie zawsze wygrywa i bardziej to zależy od tego, którą pętlę wcześniej wywołam - pierwszy test zazwyczaj wypada gorzej od tego, który jest przeprowadzany później... -.-
To co robisz nie ma sensu :|
Po prostu zobacz sobie, jak to zostało skompilowane do Assemblera i porównaj konkretne operacje.
A jak już chcesz to robić w ten sposób, to dodaj dodatkowo na samym początku pętlę tak, że testy zostaną przeprowadzone np.10 razy pod rząd.
problem w tym, że kompletnie nie znam się na asemplerze ;(
Nie musisz się znać. Jednakowe instrukcje skreślasz w obu kodach.
Te co zostali porównujesz wg cykli procesora patrząc w dokumentacje konkretnego procesora.
Teoretycznie może wyjść tak że na jednym procesorze jedno jest lepsze a na drugim drugie, aczkolwiek tylko raz zetknąłem się z taką nietypową sytuacją.