Optimizare interprocedurală ( ing. O ptimizare interprocedurală , IPO ), sau optimizare integrală a programelor ( ing. optimizarea întregului program ) - optimizare a compilatorului care utilizează analiza globală a fluxului de control și afectează multe proceduri, chiar și cele situate în module diferite, datorită la care se poate realiza o creştere semnificativă a vitezei.
Pe măsură ce programele au crescut în dimensiune, dezvoltatorii au început să-și facă codul mai lizibil și mai reutilizabil . Adesea, acest lucru duce la faptul că procedurile devin extrem de generale, în timp ce într-un anumit program te poți descurca cu un caz special. Sarcina optimizării interprocedurale este tocmai generarea unor astfel de cazuri speciale.
Optimizarea interprocedurală este realizată automat de către compilator (uneori cu directive speciale). Activarea acestuia poate duce la o creștere semnificativă a timpului de compilare. Compilatoarele care pot efectua această optimizare includ MLton și MLKit pentru Standard ML , Stalin pentru Scheme , pentru Haskell , Intel C++ Compiler .
După ce parcurge codul, compilatorul se asigură că unul dintre parametri este întotdeauna o constantă și îl distruge.
A fost void DoSomething ( Object * aObj , int aParam ) { dacă ( aObj == NULL ) throw logic_error ( "aObj==NULL" ); cout << "DoSomething(" << aObj -> name () << "," << aParam << ")" << endl ; } int main () { Obiect obj1 , obj2 ; Fă ceva ( & obj1 , 1 ); Fă ceva ( & obj2 , 1 ); returnează 0 ; } A devenit void DoSomething ( Obiect * aObj ) { dacă ( aObj == NULL ) throw logic_error ( "aObj==NULL" ); cout << "DoSomething(" << aObj -> name () << "," << 1 << ")" << endl ; } int main () { Obiect obj1 , obj2 ; Faceți ceva ( & obj1 ); Faceți ceva ( & obj2 ); returnează 0 ; }Aici compilatorul se asigură că toate apelurile virtuale care sunt executate efectiv conduc la același apel de funcție. În loc să acceseze tabelul de metode virtuale , compilatorul efectuează un apel direct de funcție.
În același exemplu, dacă Object::name() este o metodă virtuală, funcția optimizată ar arăta astfel.
void DoSomething ( Obiect * aObj ) { dacă ( aObj == NULL ) throw logic_error ( "aObj==NULL" ); cout << "DoSomething(" << Object :: name ( aObj ) << "," << 1 << ")" << endl ; }După ștergere, obțineți:
void DoSomething ( Obiect * aObj ) { cout << "DoSomething(" << Object :: name ( aObj ) << "," << 1 << ")" << endl ; }În același timp, tabelele de metode virtuale pot fi șterse .
Dacă o funcție este folosită o dată, aceasta este inclusă direct în locul din care este apelată.
Funcțiile mici pot fi incluse și direct în codul de apelare.
Multe limbaje de programare ( Pascal , Java , D ) nu au cuvântul cheie inline , iar decizia de a inline o funcție este luată de optimizator (în cazul Java , ofuscatorul ).
A fost inline int DoSomething ( int aParam ) { return aParam * aParam ; } int main () { int x = 2 ; int y = 3 ; cout << x << "^2=" << Faceți ceva ( x ) << ", " << y << "^2=" << Faceți ceva ( y ) << endl ; returnează 0 ; } A devenit int main () { int x = 2 ; int y = 3 ; cout << x << "^2=" << x * x << ", " << y << "^2=" << y * y << endl ; returnează 0 ; }