Interprocedural optimization ( eng. Inter p rocedural Optimization , IPO ) , eller fuld-program optimering af programmer ( eng. whole program optimization ) - compiler optimering , der bruger global kontrol flow analyse og påvirker mange procedurer, selv dem der er placeret i forskellige moduler, pga. hvortil der kan opnås en betydelig hastighedsforøgelse.
Efterhånden som programmer voksede i størrelse, begyndte udviklere at gøre deres kode mere læsbar og genbrugelig . Ofte fører det til, at procedurerne bliver yderst generelle, mens man i et specifikt program kan klare sig med en særlig sag. Opgaven med interprocessuelle optimering er netop genereringen af sådanne særlige tilfælde.
Interprocedural optimering udføres automatisk af compileren (nogle gange med særlige direktiver). Aktivering af det kan føre til en betydelig stigning i kompileringstiden. Compilere, der kan udføre denne optimering, omfatter MLton og MLKit for Standard ML , Stalin for Scheme , for Haskell , Intel C++ Compiler .
Efter gennemgang af koden sørger compileren for, at en af parametrene altid er en konstant og ødelægger den.
Det var void DoSomething ( Object * aObj , int aParam ) { if ( aObj == NULL ) throw logic_error ( "aObj==NULL" ); cout << "DoSomething(" << aObj -> navn () << "," << aParam << ")" << endl ; } int main () { Objekt obj1 , obj2 ; Gør Noget ( & obj1 , 1 ); Gør Noget ( & obj2 , 1 ); returnere 0 ; } Blev void Gør Noget ( Objekt * aObj ) { if ( aObj == NULL ) throw logic_error ( "aObj==NULL" ); cout << "DoSomething(" << aObj -> navn () << "," << 1 << ")" << endl ; } int main () { Objekt obj1 , obj2 ; Gør Noget ( & obj1 ); Gør Noget ( & obj2 ); returnere 0 ; }Det er her compileren sørger for, at alle virtuelle kald , der rent faktisk udføres, fører til det samme funktionskald. I stedet for at få adgang til den virtuelle metodetabel foretager compileren et direkte funktionskald.
I det samme eksempel, hvis Object::name() det er en virtuel metode, ville den optimerede funktion se sådan ud.
void Gør Noget ( Objekt * aObj ) { if ( aObj == NULL ) throw logic_error ( "aObj==NULL" ); cout << "DoSomething(" << Objekt :: navn ( aObj ) << "," << 1 << ")" << endl ; }Efter sletning får du:
void Gør Noget ( Objekt * aObj ) { cout << "DoSomething(" << Objekt :: navn ( aObj ) << "," << 1 << ")" << endl ; }Samtidig kan virtuelle metodetabeller ryddes .
Hvis en funktion bruges én gang, indgår den direkte på det sted, hvorfra den kaldes.
Små funktioner kan også inkluderes direkte i opkaldskoden.
Mange programmeringssprog ( Pascal , Java , D ) har ikke nøgleordet inline , og beslutningen om at inline en funktion tages af optimizeren (i tilfældet Java , obfuscatoren ).
Det var inline int DoSomething ( int aParam ) { returnere aParam * aParam ; } int main () { int x = 2 ; int y = 3 ; cout << x << "^2=" << DoSomething ( x ) << ", " << y << "^2=" << DoSomething ( y ) << endl ; returnere 0 ; } Blev int main () { int x = 2 ; int y = 3 ; cout << x << "^2=" << x * x << ", " << y << "^2=" << y * y << endl ; returnere 0 ; }