Wielokrotnie czytałem, że wymuszanie poprawności const w kodzie C lub C ++ jest nie tylko dobrą praktyką w odniesieniu do łatwości utrzymania, ale może również pozwolić kompilatorowi na wykonanie optymalizacji. Jednak przeczytałem też zupełnie odwrotnie - że w ogóle nie wpływa to na wydajność.
W związku z tym, czy masz przykłady, w których poprawność const może pomóc kompilatorowi w poprawieniu wydajności programu?
c++
performance
const-correctness
shuhalo
źródło
źródło
const
nastąpiła różnica w wydajności: stackoverflow.com/questions/1121791/… . Zasadniczo była to jednak kwestia jakości wdrożenia.const
nie określił, czy kompilator może legalnie dokonać optymalizacji, po prostu zdarzyło się, że wersja kompilatora nie wykonała tego, gdy jej brakowało.Odpowiedzi:
const
Poprawność nie może poprawić wydajność, ponieważconst_cast
imutable
są w języku i pozwól kod do conformingly łamać zasady. Jest to jeszcze gorsze w C ++ 11, gdzie twojeconst
dane mogą np. Być wskaźnikiem do astd::atomic
, co oznacza, że kompilator musi uwzględniać zmiany wprowadzone przez inne wątki.To powiedziawszy, dla kompilatora jest trywialne, aby spojrzeć na kod, który generuje, i określić, czy faktycznie zapisuje do danej zmiennej, i odpowiednio zastosować optymalizacje.
To powiedziawszy,
const
poprawność to dobra rzecz w odniesieniu do łatwości konserwacji. W przeciwnym razie klienci Twojej klasy mogą złamać wewnętrznych członków tej klasy. Weźmy na przykład pod uwagę standardstd::string::c_str()
- gdyby nie mógł zwrócić wartości stałej, byłbyś w stanie poradzić sobie z wewnętrznym buforem łańcucha!Nie używaj
const
ze względu na wydajność. Używaj go ze względów konserwacyjnych.źródło
const
są drogowskazami z napisem „robisz coś głupiego”.Tak, może.
Większość z nich
const
jest wyłącznie dla korzyści programisty i nie pomaga kompilatorowi w optymalizacji, ponieważ ich odrzucenie jest legalne, a więc nie mówią kompilatorowi niczego przydatnego do optymalizacji. Jednak niektórychconst
plików nie można (zgodnie z prawem) odrzucić i dostarczają one kompilatorowi przydatnych informacji do optymalizacji.Na przykład dostęp do zmiennej globalnej zdefiniowanej za pomocą
const
typu może być wbudowany, podczas gdy nie można wstawić tej bezconst
typu, ponieważ może się to zmienić w czasie wykonywania.https://godbolt.org/g/UEX4NB
C ++:
int foo1 = 1; const int foo2 = 2; int get_foo1() { return foo1; } int get_foo2() { return foo2; }
jako M:
foo1: .long 1 foo2: .long 2 get_foo1(): push rbp mov rbp, rsp mov eax, DWORD PTR foo1[rip] ; foo1 must be accessed by address pop rbp ret get_foo2(): push rbp mov rbp, rsp mov eax, 2 ; foo2 has been replaced with an immediate 2 pop rbp ret
W praktyce należy pamiętać, że chociaż
const
może poprawić wydajność, w większości przypadków nie będzie lub będzie, ale zmiana nie będzie zauważalna. Podstawową użytecznościąconst
nie jest optymalizacja.Steve Jessop podaje inny przykład w swoim komentarzu do pierwotnego pytania, w którym pojawia się coś, o czym warto wspomnieć. W zakresie blokowym kompilator może wywnioskować, czy zmienna zostanie zmutowana i odpowiednio zoptymalizować, niezależnie od tego
const
, ponieważ kompilator może zobaczyć wszystkie zastosowania zmiennej. W przeciwieństwie do powyższego przykładu, nie można przewidzieć, czyfoo1
zostanie zmutowany, ponieważ można go zmodyfikować w innych jednostkach tłumaczeniowych. Przypuszczam, że hipotetyczny, czujący ultra-kompilator mógłby przeanalizować cały program i określić, czy można go uzyskać w trybie inlinefoo1
... ale prawdziwe kompilatory nie mogą.źródło
z mojego doświadczenia, nie
W przypadku zmiennych skalarnych kompilator jest w stanie określić każdą zmianę wartości i samodzielnie przeprowadzić niezbędną optymalizację.
W przypadku wskaźników tablicowych poprawność const nie gwarantuje, że wartości są naprawdę stałe w przypadku potencjalnych problemów z aliasowaniem. Dlatego kompilator nie może używać samego modyfikatora const do przeprowadzania optymalizacji
jeśli szukasz optymalizacji, powinieneś rozważyć
__restrict__
specjalne modyfikatory / atrybuty funkcji: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.htmlźródło
Trochę stary, ale nadal działa: http://www.gotw.ca/gotw/081.htm I trochę więcej: http://cpp-next.com/archive/2009/08/want-speed-pass-by -wartość/
źródło