Przemysław Sroczyński
Języki Obiektowe - Laboratorium
Porównanie efektywności funkcji rozwijalnych inline i statycznych ze zwykłymi funkcjami składowymi.
1.Teoria
Operacje często powtarzające się w programie najwygodniej jest zadeklarować jako funkcję. Ma to kilka ważnych zalet.
- wywołanie pojedynczej funkcji jest dużo bardziej czytelne niż jej rozwinięcie.
- łatwiej zmienić środek procedury niż poprawiać program użytkownika we wszystkich miejscach wystąpienia rozwinięć.
- argumenty przekazywane do funkcji są zawsze sprawdzane pod względem zgodności typów (błędy są wykrywane już w czasie kompilacji).
- istnieje możliwość łatwego wykorzystania raz już napisanych funkcji w innych programach.
Jednak funkcje są znacznie powolniejsze niż analogiczne ich rozwinięcia. Szczególnie widoczne jest to przy krótkich funkcjach pobierających dużo argumentów. Trzeba skopiować argumenty, przechować zawartości rejestrów funkcji wywołującej (przeważnie na stosie),zapamiętać adres powrotu, wykonać skok do adresu procedury i zainicjować zmienne lokalne funkcji. Powrót z funkcji też nie jest szybki. Wykonywany jest skok powrotny, odświeżana zawartość rejestrów.
Rozwiązaniem tego problemu są funkcje zdefiniowane jako "inline". Ich treść jest rozwijana w każdym miejscu wystąpienia wywołania. Umożliwia to tworzenie szybkiego i jasnego kodu (alternatywą jest tworzenie #define-ów ,które są jednak skomplikowane i wymagają dużej praktyki).
Żeby zdefiniować funkcję rozwijalną trzeba przed jej definicją użyć specyfikatora inline. Drugą metodą jest zdefiniowanie metody wewnątrz definicji klasy. Funkcja taka automatycznie staje się rozwijalną.
Innym modyfikatorem dodającym nowe ciekawe możliwości funkcji jest modyfikator "static". Umożliwia on zdefiniowanie wewnątrz klasy funkcji która może być wywołana nawet wtedy kiedy nie ma żadnego obiektu tej klasy. Funkcja ta ma jednak kilka ograniczeń. Może korzystać tylko ze zmiennych klasy zdefiniowanych jako "static" oraz innych funkcji statycznych.
2.Testy
add2.... - dodanie 2 liczb (2 argumenty)
add10.... - dodanie 10 liczb (10 argumentów)
2.1 Środowisko: Microsoft Windows 98;Microsoft Visual C++; Intel Vtune 4.0
tryb: debug
pomiar: czas w którym program znajdował się w określonej procedurze w stosunku do czasu trwania całego programu. Niedokładności związane z pułapkami zakładanymi przy kompilacji w trybie debug (int 3)
wyniki:
add2 = 12,42%
add2static = 11,95%
add2inline = 13,48%
add10 = 15,82%
add10static = 14,09%
add10inline = 14,95%
kod: Kod assemblerowy wnętrza funkcji i wywołania dla funkcji inline i normalnej jest identyczny (Funkcje inline ani static nie są rozwijane).Różnice mogą być spowodowane ułożeniem w pamięci i pułapkami debuggera.
tryb: release
pomiar: Procesor co stalą liczbę taktów wysyłał przerwanie sprawdzające w jakim stanie znajduje się procesor. Jednostki oznaczają ile z tych zdarzeń wystąpiło podczas wykonywania programu zawierającego 10^9 wywołań funkcji. Jest to proporcjonalne do czasu wykonania programu.
wyniki:
add2 = 26904
add2static = 20137
add2inline = 20250
add10 = 106261
add10static = 44230
add10inline = 43655
kod: Funkcje inline i static zostały rozwinięte w miejscach wywołań. Spowodowało to znaczne przyspieszenie widoczne zwłaszcza przy dużej liczbie argumentów.
2.2 Środowisko: Linux : gcc 2.95 :time
tryb: bez optymalizacji
pomiar: mało dokładny pomiar czasu poleceniem time. Program wykonuje 10^9 pętli wywołującej badane funkcje.
wyniki:
add2 = 1m12 s
add2static = 1m7s
add2inline = 1m20s
add10 =
add10static = 4m13s
add10inline = 4m13s
kod: Kod w assemblerze (opcja -S kompilatora) pokazuje , że rozwinięcia funkcje inline nie są wstawiane w miejscach wywołania i nie różnią się od zwykłych.
tryb: optymalizacja (opcja -O2)
wyniki:
add2 = 37s
add2static = 8.2s
add2inline = 8s
add10 = 1m37s
add10static = 12.89s
add10inline = 12.80s
kod: Rozwinięte zostały funkcje zadeklarowane jako inline i static. Zwykle nadal są wywoływane poprzez instrukcję "call"
3.Wnioski
Specyfikator inline i static mogą znacznie przyspieszyć działanie programu, jednak użycie ich nie jest równoznaczne z rozwinięciem funkcji przy kompilacji. Jest to tylko zalecenie dla kompilatora który rzadko zwraca na nie uwagę. Jeśli nie włączy się optymalizacji kompilator nie rozwija tych funkcji. Kiedy się ją włączy kompilator rozwija wszystkie funkcje które mu pasują czyli nawet te które nie miały zadeklarowanego specyfikatora. Istnieje też pewien błąd w niektórych kompilatorach prowadzący do ich zawieszania. Wystarczy zadeklarować jako inline funkcję rekurencyjną.
Wyszukiwarka
Podobne podstrony:
klucz test zawodowy Y6ZUUDOVTest dla kierowcy[1]candi self testpytania2009cz1 testMaturaSolutionsAdv Unit 4 Progress test BTest II III etap VIII OWoUEprzykładowy test AUnit 7 Progress test B1 Test Starożytna Grecja gr1 licOTWP 2010 TEST III2015 matura JĘZYK NIEMIECKI poziom rozszerzony TESTTest DT moduł 3 4więcej podobnych podstron