Wskaźnik - wyłuskanie wartości (koszt operacji)

0

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ź.

0

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.

0

Samo wyłuskanie to tylko formalność (o ile masz naprawdę wskaźnik).

0

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

0

W tym co opisujesz już nie jest samo wyłuskanie, tylko zapisywanie wartości wyłuskanego wskaźnika, a to już zajmuje czas.

0

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ę!

0

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
0

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.

0

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.

0

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 ;-);

0

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... -.-

0

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.

0

problem w tym, że kompletnie nie znam się na asemplerze ;(

0

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ą.

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