częste uŻywanie funkcji (C++)

0

Hey, mam pytanie. Chciałbym stworzyć funkcję, która jest niedużych rozmiarów i będzie bardzo często wykonywana przykładowo funkcja podnosząca liczbę do kwadratu w programie, który robi to naprawdę często!
Czy w takim przypadku lepiej przekazywać wartość do funkcji przez wartość czy przez wskaźnik/referencję?
tj. czy lepiej to zrobić tak:

double kwadrat(const double* x){//lub (const double & x)
return(x*x);
} 

Czy może lepiej zrobić to tak:

 double kwadrat(double x){
return(x*x);
}

Który sposób jest szybszy i bardziej praktyczny?
Czy są jakieś przeciwwskazania do używania wskaźnika/referencji w tym wypadku?
W programie nie chodzi o to, żeby modyfikować wprowadzoną zmienną do funkcji, ale żeby się to szybciej wykonywało - stąd const.
z góry dzięki za pomoc :)

0
  1. uŻywanie
  2. Nie ma w zasadzie większego znaczenia. double może być po prostu trochę większy niż int, ale to nie funkcja rekurencyjna żeby się tym przejmować. Możesz dopisać sobie inline przed tą funkcją, ale to tylko dla własnej satysfakcji bo kompilator sam uzna czy zrobić inline czy nie.
0

Najlepiej wywal tą funkcję i pisz bezpośrednio w kodzie x*x. Ewentualnie inline, ale nie ma gwarancji, że kompilator cię posłucha.

1

Absolutnie nie pisz w kodzie wielokrotnie x*x, bo jak się okaże że jednak miało być x3 a nie x2 to będziesz poprawiał w N miejscach, o którymś zapomnisz i będziesz debugował do końca życia!

0

A nie ma znaczenia czy zmienna jest przekazywana przez wartość czy przez referencję? - nawet minimalnej?

0

Aha i podany przykład podnoszenia do kwadratu jest tylko przykładem - w rzeczywistości będzie to nieco bardziej rozbudowana funkcja

0

Ciężko mi jest wyobrazić sobie sytuację, w której kompilator nie zoptymalizuje tego kodu. Prawdopodobnie nie ma to żadnego znaczenia. Dlaczego zadajesz takie pytanie na forum? Przecież chyba Tobie najłatwiej to sprawdzić w kontekście całego kodu.

0
beginnerX napisał(a)

A nie ma znaczenia czy zmienna jest przekazywana przez wartość czy przez referencję? - nawet minimalnej?

Znaczenie jest zasadnicze.
W przypadku liczb częściej stosuje się przekazywanie przez wartość lub przez referencję (jeśli potrzeba zmienić parametr w funkcji).
W przypadku obiektów, struktur - przez wskaźnik, referencję i inteligentny wskaźnik.

Dlaczego? Dla spokoju ducha. Przekazywanie przez wskaźnik jest gorsze do utrzymania i debugowania.
A zysku w wydajności prawdopodobnie niewiele lub brak.

0

@beginnerX jak będziesz przekazywał jakieś super-ciężkie obiekty to pewnie warto referencją/wskaźnikiem. Ale jak mówimy o 4 czy 8 bajtach to nie ma sensu kombinować.

0
beginnerX napisał(a)

A nie ma znaczenia czy zmienna jest przekazywana przez wartość czy przez referencję? - nawet minimalnej?

Oczywiście że ma! Zmienna przekazana przez wartość nie ulegnie zmianie "na zewnątrz" funkcji choćbyśmy nie wiadomo jakie cuda z nią w środku wyprawiali. Zmiana wartości wewnątrz funkcji zmiennej przekazanej przez referencję będzie widoczna "na zewnątrz" funkcji. W przykładzie który podałeś nie ma to znaczenia, ponieważ nie podstawiasz nic pod x.

0

Ok, dzięki - przyjąłem :)

0

To i tak nie ma znaczenia, bo kompilator to zoptymalizuje. Gdybyś np. używał wskaźników na funkcje i ta funkcja kwadrat byłaby przekazywana jako jakiś parametr, a potem miałbyś jej użyć, to może rzeczywiście wtedy szybciej będzie przekazywać przez wartość. No ale to są jakieś ekstremalne przypadki. Pewnie Ciebie nie dotyczą.

0

Dobrą zasadą jest przekazywanie zmiennych przez wartość, lub stałą referencję, gdy wartość zmiennej się nie zmienia, a przez wskaźnik, gdy może się zmienić. Dzięki temu podczas wywoływania funkcji wiesz, kiedy wartości zmiennych mogą ulec zmianie, w przypadku używania także normalnych referencji/stałych wskaźników tracisz tę ważną informację.

Co do wydajności, to trzeba zawsze to mierzyć. Zrób program z najprostszą wersją, zmierz, zmodyfikuj i zobacz jak się czas wykonania zmienił. Może w tym wypadku sama funkcja nie powoduje narzutu (bo jest np. zinlineowana), ale da się te operacje przyspieszyć przez wektoryzację.

0

Ja powiem Ci tak - czego byś w takiej prostej funkcji nie podopisywał - const, inline czy referencji, zdrowy kompilator z włączonymi opcjami optymalizacji wsadzi ten kod bezpośrednio w miejsce wywołania i już.

A propos przyśpieszenia za pomocą przekazywania przez referencję: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

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