Kiedy używać funkcji inline, a kiedy jej nie używać?

Wiem, że inline jest podpowiedzią lub prośbą do kompilatora i służy do unikania kosztów wywołania funkcji.

Więc na jakiej podstawie można określić, czy dana funkcja jest kandydatem do inliningu, czy nie ? W którym przypadku należy unikać inlining ?

 201
Author: BenMorel, 2009-12-19

14 answers

Unikanie kosztów wywołania funkcji to tylko połowa historii.

Do:

  • użyj inline zamiast #define
  • bardzo małe funkcje są dobrymi kandydatami do inline: szybszy kod i mniejsze pliki wykonywalne (więcej szans na pozostanie w pamięci podręcznej kodu)
  • funkcja jest mała i wywoływana bardzo często

Nie:

  • Duże funkcje: prowadzi do większych plików wykonywalnych, co znacznie pogarsza wydajność niezależnie od z tego powodu, w przeciwieństwie do innych systemów, nie jest to możliwe.]}
  • funkcje liniowe, które są związane We / Wy
  • funkcja jest rzadko używana
  • konstruktory i destruktory: nawet gdy są puste, kompilator generuje dla nich kod
  • łamanie kompatybilności binarnej podczas tworzenia bibliotek:
    • inline a existing function
    • zmiana funkcji inline lub uczynienie funkcji inline nie-inline: poprzednia wersja biblioteki nazywa starą realizacja

Podczas tworzenia biblioteki, w celu uczynienia klasy rozszerzalną w przyszłości należy:

  • Dodaj nie - inline wirtualny Destruktor, nawet jeśli ciało jest puste
  • niech wszystkie konstruktory nie są inline
  • zapisuje Nie-inline implementacje konstruktora kopiującego i operatora przypisania, chyba że klasa nie może być skopiowana przez wartość

Pamiętaj, że słowo kluczowe inline jest podpowiedzią dla kompilatora: kompilator może nie należy decydować o inline funkcji i może ona zdecydować o inline funkcji, które nie zostały oznaczone inline w pierwszej kolejności. Generalnie unikam oznaczania funkcji inline (pomijając może przy pisaniu bardzo małych funkcji).

Jeśli chodzi o wydajność, mądrym podejściem jest (jak zawsze) profilowanie aplikacji, a następnie inline zestaw funkcji reprezentujących wąskie gardło.

Bibliografia:


W 2007 roku, po raz pierwszy w Polsce, pojawiła się nowa wersja C++.]}

Funkcję można zdefiniować jako inline. Na przykład:

inline int fac(int n)
{
  return (n < 2) ? 1 : n * fac(n-1);
}

Specyfikator inline jest wskazówką dla kompilatora, że powinien próbować generowanie kodu dla wywołania fac() inline, a nie ustanawianie kodu dla funkcji raz, a następnie wywołanie za pomocą zwykłego mechanizmu wywołania funkcji. Inteligentny kompilator może wygenerować stałą 720 dla wywołania fac(6). Możliwość wzajemnie rekurencyjnych funkcji inline, funkcji inline, które rekurencyjnie lub nie w zależności od wejścia, itp., uniemożliwia zagwarantowanie, że każde wywołanie funkcji inline jest rzeczywiście inlined. Stopnia sprytności kompilatora nie można określić, tak więc jeden kompilator może generować 720, inny 6 * fac(5), a jeszcze inny nie-inlined wywołanie fac(6).

Aby inlining był możliwy w przypadku braku niezwykle sprytnych funkcji kompilacji i łączenia, definicja–a nie tylko deklaracja-funkcji inliniowej musi mieć zakres (§9.2). inline especifier nie wpływa na semantykę funkcji. W szczególności, funkcja inline nadal ma unikalny adres, a więc ma zmienne static (§7.1.2) inline funkcja.

EDIT2: ISO-IEC 14882-1998, 7.1.2 Specyfikacja funkcji

Deklaracja funkcji (8.3.5, 9.3, 11.4) ze specyfikatorem inline deklaruje funkcję inline. Inline specifier wskazuje implementacji, że inline substitution of the function body at the point of call ma być preferowane do zwykłego mechanizmu wywołania funkcji. Implementacja nie jest wymagana do wykonania tego zastąpienia inline w punkcie wywołania; jednak, nawet jeśli to inline pomija się podstawienie, nadal przestrzega się innych reguł dotyczących funkcji wbudowanych określonych w pkt 7.1.2.

 220
Author: Gregory Pakosz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-20 18:26:01

inline ma niewiele wspólnego z optymalizacją. inline jest instrukcją dla kompilatora, aby nie generował błędu, jeśli dana funkcja występuje wielokrotnie w programie oraz obietnicą, że definicja pojawi się w każdym używanym tłumaczeniu i wszędzie, gdzie się pojawi, będzie miała dokładnie tę samą definicję.

Biorąc pod uwagę powyższe zasady, inline nadaje się do krótkich funkcji, których ciało nie wymaga włączenia dodatkowych zależności od tego, co tylko potrzebne byłoby oświadczenie. Za każdym razem, gdy napotkana jest definicja, musi być ona parsowana, a kod jej ciała może zostać wygenerowany, więc implikuje to pewien kompilator nad funkcją zdefiniowaną tylko raz w jednym pliku źródłowym.

Kompilator może inline (tzn. zastąpić wywołanie funkcji kodem, który wykonuje tę akcję tej funkcji) dowolne wywołanie funkcji, które wybierze. Kiedyś było tak, że "oczywiście" nie mógł wbudować funkcji, która nie została zadeklarowana w tym samym Jednostka tłumaczenia jako wywołanie, ale z rosnącym wykorzystaniem optymalizacji czasu łącza nawet to nie jest prawda teraz. Równie prawdziwy jest fakt, że funkcje oznaczone inline mogą nie być inlinowane.

 61
Author: CB Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 10:40:27

Nakazanie kompilatorowi wbudowania funkcji jest optymalizacją, a najważniejszą zasadą optymalizacji jest to, że przedwczesna optymalizacja jest źródłem wszelkiego zła. Zawsze pisz przejrzysty kod (używając wydajnych algorytmów), następnie profiluj swój program i optymalizuj tylko funkcje, które trwają zbyt długo.

Jeśli okaże się, że dana funkcja jest bardzo krótka i prosta, i jest wywoływana dziesiątki tysięcy razy w ciasnej pętli wewnętrznej, może to być dobry kandydat.

Ty może być jednak zaskoczony - wiele kompilatorów C++ automatycznie wbuduje małe funkcje dla Ciebie - i mogą zignorować twoje żądanie inline, zbyt.

 10
Author: dmazzoni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 08:09:08

Najlepszym sposobem, aby się dowiedzieć, jest profilowanie programu i oznaczanie małych funkcji, które są wywoływane wiele razy i przepalanie przez cykle procesora, które jako inline. Słowo kluczowe jest tutaj "małe" - gdy narzut wywołania funkcji jest znikomy w porównaniu z czasem spędzonym w funkcji, nie ma sensu ich wstawiać.

Inne użycie, które sugeruję, to jeśli masz małe funkcje, które są wywoływane w kodzie krytycznym wydajności wystarczająco często, aby pamięć podręczna nie była istotna, prawdopodobnie powinieneś wbudować te też. Znowu, to coś, co profiler powinien ci powiedzieć.

 5
Author: Timo Geusch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 08:09:54

Przedwczesna optymalizacja jest źródłem wszelkiego zła!

Zazwyczaj wpisuję tylko "getters" i "setters". Gdy kod działa i jest stabilny, profilowanie może pokazać, które funkcje mogą skorzystać z inliningu.

Z drugiej strony, większość współczesnych kompilatorów ma całkiem dobre algorytmy optymalizacyjne i wbuduje to, co powinieneś mieć za siebie.

Reasuming -- napisz funkcje Jednowierszowe inline, i martw się o innych później.

 5
Author: Kornel Kisielewicz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 08:39:59

Funkcje Inline Mogą poprawić wydajność kodu, eliminując potrzebę wpychania argumentów do stosu. jeśli dana funkcja znajduje się w krytycznej części kodu, powinieneś podjąć decyzję inline, a nie inline w części optymalizacyjnej projektu,

Możesz przeczytać więcej o inlines w C++ faq

 2
Author: Alon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-27 17:36:15

Najlepszym sposobem byłoby zbadanie i porównanie wygenerowanych instrukcji dla inlined i nie inlined. Jednak zawsze bezpiecznie jest pominąć inline. Używanie inline może prowadzić do kłopotów, których nie chcesz.

 1
Author: wallyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 08:15:26

Często używam funkcji inline nie jako optymalizacji, ale aby Kod był bardziej czytelny. Czasami sam kod jest krótszy i łatwiejszy do zrozumienia niż komentarze, nazwy opisowe itp. Na przykład:

void IncreaseCount() { freeInstancesCnt++; }

Czytelnik od razu zna pełną semantykę kodu.

 1
Author: danatel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 09:33:31

Należy używać kwalifikatora inline tylko wtedy, gdy kod funkcji jest mały.Jeśli funkcje są większe, powinieneś preferować normalne funkcje, ponieważ oszczędność miejsca w pamięci jest warta stosunkowo niewielkiego poświęcenia w szybkości wykonania.

 1
Author: nitish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-10 09:24:59

Generalnie przestrzegam zasady kciuka, gdzie robię funkcję z 3-4 prostymi instrukcjami jako inline. Warto jednak pamiętać, że jest to tylko wskazówka dla kompilatora. Ostateczne wywołanie, aby uczynić go inline lub nie jest pobierane tylko przez kompilator. Jeśli jest więcej niż te wiele instrukcji, nie zadeklaruję inline, ponieważ w przypadku głupiego kompilatora może to spowodować zawężenie kodu.

 0
Author: Naveen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 08:07:26

Decydując się na użycie inline, zazwyczaj mam na uwadze następujący pomysł: na nowoczesnych maszynach opóźnienie pamięci może być większym wąskim gardłem niż obliczenia surowe. Funkcje Inlining, które są często wywoływane, zwiększają rozmiar pliku wykonywalnego. Co więcej, taka funkcja może być przechowywana w pamięci podręcznej kodu procesora, co zmniejszy liczbę błędów pamięci podręcznej, gdy ten kod musi być dostępny.

Dlatego musisz sam zdecydować: czy inlining zwiększa lub zmniejsza rozmiar wygenerowanego kodu maszynowego? Jak prawdopodobne jest, że wywołanie funkcji spowoduje brak pamięci podręcznej? Jeśli jest to pieprzone w całym kodzie, powiedziałbym, że prawdopodobieństwo jest wysokie. Jeśli jest on ograniczony do pojedynczej ciasnej pętli, prawdopodobieństwo jest miejmy nadzieję niskie.

Zazwyczaj używam inliningu w przypadkach, które wymieniam poniżej. Jednak tam, gdzie naprawdę zależy ci na wydajności, profilowanie jest niezbędne. Ponadto możesz sprawdzić, czy kompilator rzeczywiście bierze podpowiedź.

  • krótkie procedury, które są wywoływane w ciasnej pętli.
  • bardzo podstawowe funkcje (get / set) i wrapper.
  • kod szablonu w plikach nagłówkowych niestety automatycznie uzyskuje podpowiedź w wierszu.
  • Krótki kod, który jest używany jak makro. (Np. min () / max ())
  • krótkie procedury matematyczne.
 0
Author: Rehno Lindeque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 08:50:54

Również metoda inline ma poważne skutki uboczne przy utrzymaniu dużych projektów. Gdy kod inline zostanie zmieniony, wszystkie pliki, które go używają, zostaną automatycznie odbudowane przez kompilator (jest to dobry kompilator). To może zmarnować dużo czasu na rozwój.

Gdy metoda inline jest przenoszona do pliku źródłowego i nie jest już inlinowana, cały projekt musi zostać przebudowany (przynajmniej takie było moje doświadczenie). A także, gdy metody są konwertowane do inline.

 0
Author: Thomas Matthews,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 20:05:30

Gdy uważasz, że Twój kod jest na tyle mały, aby być używany jako inline i pamiętaj funkcja inline Duplikuj kod i wklej go, gdy funkcja jest wywoływana, więc może to być wystarczająco dobre, aby zwiększyć czas wykonania, ale zwiększone zużycie pamięci również. Nie możesz używać funkcji inline, gdy używasz funkcji pętli/zmiennej statycznej/rekurencyjnej/przełącznika/goto / wirtualnej. Wirtualne oznacza czekać do czasu uruchomienia i inline oznacza podczas kompilacji, więc nie mogą być używane jednocześnie.

 0
Author: sachin pathak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-03 09:47:10

Przeczytałem kilka odpowiedzi i widzę, że brakuje niektórych rzeczy.

Zasada, której używam, to nie używać inline, chyba że chcę, aby to było inline. Wygląda głupio, teraz Wyjaśnienie.

Kompilatory są wystarczająco inteligentne, a krótkie funkcje zawsze tworzą inline. I nigdy nie sprawia, że long działa jako inline, chyba że programista powiedział, aby to zrobić.

Wiem, że inline to podpowiedź lub prośba do kompilatora

Faktycznie {[1] } jest porządkiem dla kompilatora, nie ma wyboru i po inline słowo kluczowe sprawia, że cały kod jest wbudowany. Więc nigdy nie można użyć słowa kluczowego inline, A kompilator zaprojektuje najkrótszy kod.

Więc kiedy używać inline?

Aby użyć, jeśli chcesz mieć jakiś kod w linii. Znam tylko jeden przykład, ponieważ używam go tylko w jednej sytuacji. Jest to uwierzytelnianie użytkownika.

Na przykład mam taką funkcję:

inline bool ValidUser(const std::string& username, const std::string& password)
{
    //here it is quite long function
}

Bez względu na to, jak duża jest ta funkcja, chcę ją mieć jako inline, ponieważ sprawia, że moje oprogramowanie jest trudniejsze do złamania.

 -2
Author: ST3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-13 18:42:05