2013-07-07 6 views
6

Biorąc pod uwagę następujący kod:Czy optymalizatorzy przenoszą tymczasowe typy inne niż POD z pętli?

while(is_running) 
{ 
    std::vector<buffer> buffers; 

    // fill buffers 

    // use buffers 
} 

Czy współczesne kompilatory wykonać następującą transformację?

std::vector<bufer> buffers; 

while(is_running) 
{ 
    // fill buffers 

    // use buffers 

    buffers.clear(); 
} 
+0

Dlaczego uważasz, że drugi byłby bardziej wydajny? Czy profilowałeś? –

+1

@LuchianGrigore Jedynym powodem, dla którego mogę myśleć jest to, że pierwsza wersja musi mieć przydzielanie/de-alokacja na cykl pętli, a druga nie musi tak być. – juanchopanza

+0

@juanchopanza: Prawidłowo, drugi nie będzie nieprzypadkowo przydzielać/zwalniać podczas każdej iteracji pętli. – ronag

Odpowiedz

4

Jedynym sposobem, aby wiedzieć na pewno będzie test, ale Byłbym raczej zaskoczony, aby zobaczyć optymalizator przeprowadzenia tej optymalizacji.

Aby nawet zacząć wykonywać tej optymalizacji kompilator musiałby albo 1) wiedzieć wystarczająco dużo o wewnętrznych o funkcjach związanych z „zrealizować” (na przykład), że operator new i operator delete są zasadniczo swoimi lustrzanymi odbiciami albo inny, lub 2) musiałby generować wszystkie kodu dla wszystkich inline funkcji (całą drogę w dół do wywołań operator new i operator delete i mają dość inteligencji, aby móc wyprowadzić ten sam wniosek z kodem.

Z trudem mogę sobie wyobrazić pierwszy, ale nie pamiętam, że kiedykolwiek go widziałem. Biorąc pod uwagę zawiłości typowego zarządcy sterty, drugi uderza m e jako naprawdę niewiarygodne.

Podsumowanie: Byłem zaskoczony wcześniej i jestem pewien, że znów będę - ale będzie to większa niespodzianka niż większość.

+2

Ponadto kompilator musiałby się martwić efektami ubocznymi, na przykład zmiennych globalnych - w tym na przykład 'errno'. –

0

Byłbym zaskoczony tym, że kompilator faktycznie zna pojemniki standardowe i wywołuje ich metody bez mojej wyraźnej prośby. Jeśli tak było, wyobraź sobie, jak należy rozbudowywać logikę kompilatora za każdym razem, gdy zostanie wydany nowy moduł biblioteki!

Byłoby jednak interesujące, aby dowiedzieć się, że niektóre kompilatory C++ mają pewną wiedzę o bibliotece standardowej.

EDYCJA: Ok, znalazłem przykład takiej wiedzy: bazujące na C++ 11 pętle stosują std :: begin i std :: end na zakresy.

W każdym razie, to my, programiści, musimy naprawdę zrozumieć, co piszemy w kodzie i ustalić sposoby jego optymalizacji. Kompilator powinien po prostu przetłumaczyć nasze instrukcje, stosując tylko małe (ale znaczące) optymalizacje (takie jak wstawianie, kopiowanie itp.).