Optymalizacja oprogramowania - trudne pytanie

0

Panowie,

Podczas rozmowy o pracę dostałem następujące pytanie:
"W czym może być gorszy kod zoptymalizowany od tego, który nie został zoptymalizowany?"

Pytanie tyczy dwóch funkcji/metod robiących to samo. Pierwsza jest znacznie wolniejsza od drugiej (zoptymalizowanej) - dajmy na to 30 razy. Obie przeszły identyczne testy jednostkowe, więc możemy uznać, że ich poprawność działania jest identyczna. W czym więc ta szybsza może być gorsza? Strzeliłem, że być może wykorzystuje więcej pamięci (koleś na rozmowie mówił, że to nie to), a potem, że może powoduje spowolnienie wykonywania innych części kodu lub wątków (większy priorytet). Tutaj również nie trafiłem. W czym może być jeszcze różnica?

0

Dla mnie to ona może być mniej czytelna. Ale pytanie beznadziejne.
Poza tym odpowiedź o ilości pamięci też jest poprawna bo z tego co piszesz chodzi o optymalizację pod względem szybkości.

0

W zrozumieniu? W łatwości modyfikowania?

0
Afish napisał(a)

W zrozumieniu? W łatwości modyfikowania?

Faktycznie, o tym nie pomyślałem (cały czas miałem w głowie porównywanie już skompilowanego kodu) - to być może był ten brakujący element.

0
Afish napisał(a)

W zrozumieniu? W łatwości modyfikowania?

To jest prawidłowa odpowiedź.
Czasami warto zostawić jedno przypisanie więcej lub wywołanie funkcji, aby zyskać na czytelności - o ile nie wpływa to znacząco na czas wykonywania.

Poza tym optymalizować można pod wieloma względami - jeśli optymalizujemy tylko pod względem prędkości to możliwe, że zwiększa się zużycie pamięci.

Z kolei gdy kod jest prze-optymalizowany (np. za dużo inline lub loop unroll) to nagle przestaje być kodem lokalnym i może się przestać mieścić w cache'u (chociaż nie wiem jak to możliwe - przy tych rozmiarach które są obecnie).

0

nagle przestaje być kodem lokalnym i może się przestać mieścić w cache'u (chociaż nie wiem jak to możliwe - przy tych rozmiarach które są obecnie).

Jeśli nie mieści się w cache L1 dla kodu, czy też w trace cache (jak w niektórych Pentium IV czy Sandy Bridge) to ciągłe ładowanie/ dekodowanie kodu może być wąskim gardłem.

Jeśli chodzi o przypisania - kod w procesie optymalizacji jest transformowany do SSA (static single assingment), a potem usuwane są wspólne podwyrażenia. Deklarowanie nowych lokalnych stałych wcale nie musi zwiększać złożoności obliczeniowej, czy powodować większego zużycia pamięci.

Jestem generalnie zwolennikiem const correctness w C++, zresztą kompilatorowi łatwiej zoptymalizować program, jeżeli explicite podamy mu informację, że jakieś tam pola się nie zmieniają (są const). Myślę, że przy odpowiedniej dawce const corecctness w kodzie współczesne kompilatory są w stanie zoptymalizować jakiejś wyszukane szablony do takiej samej postaci jak wprost zoptymalizowane konstrukcje.

0

Ja dodałbym jeszcze to że taki zoptymalizowany kod może być ciężki w debugowaniu(przejście przez testy nie gwarantuje, że kod jest w 100% poprawny).

0
Hostel napisał(a)

Ja dodałbym jeszcze to że taki zoptymalizowany kod może być ciężki w debugowaniu(przejście przez testy nie gwarantuje, że kod jest w 100% poprawny).

Miałem ostatnio przed oczami mniej więcej taki kod:

// duża petla a na jej końcu: 
if (warunek)
  zmiennaA = zmiennaB;
else
  zmiennaB = zmiennaA;

Podejrzewam że ktoś to tak napisał, bo mu było żal zrobić jedno przypisanie więcej, ale bądź potem mądry i taki kod analizuj...

0

Kod zoptymalizowany może charakteryzować się tym, że jest sztywny i ciężej idzie dostosować go do ewentualnych zmian. Inny stopień optymalizacji jaki przychodzi mi do głowy to stosowanie np. funkcji typowo natywnych. Wiadomo to podnosi wydajność, ale tym samym ogranicza kod do mniejszej liczby platform. Można też większa wydajność osiągnąć stosując języki niższego poziomu np. jakiś algorytm wykonać w C a potem to wykorzystać w pythonie. Wtedy jako problem dodatkowo można wskazać większe ryzyko błędu, bo taki C na pewno jest mniej bezpieczny.

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