Эффективность и структура
За исключением операторов new, delete, type_id, dynamic_cast, throw и блока try, отдельные выражения и инструкции C++ не требуют поддержки во время выполнения.
Хотелось бы отметить, что есть еще несколько очень важных мест, где мы имеем неожиданную и порой весьма существенную "поддержку времени выполнения". Это конструкторы/деструкторы (сложных) объектов, код создания/уничтожения массивов объектов, пролог/эпилог создающих объекты функций и, отчасти, вызовы виртуальных функций.
Для демонстрации данной печальной особенности рассмотрим следующую программу (замечу, что в исходном коде текст программы, как правило, разнесен по нескольким файлам для предотвращения агрессивного выбрасывания "мертвого кода" качественными оптимизаторами): #include <stdio.h> #include <stdlib.h> #include <time.h>
struct A { A(); ~A(); };
void ACon(); void ADes();
void f1() { A a; }
void f2() { ACon(); ADes(); }
long Var, Count;
A::A() { Var++; } A::~A() { Var++; }
void ACon() { Var++; } void ADes() { Var++; }
int main(int argc,char** argv) { if (argc>1) Count=atol(argv[1]);
clock_t c1,c2; { c1=clock();
for (long i=0; i<Count; i++) for (long j=0; j<1000000; j++) f1();
c2=clock(); printf("f1(): %ld mlns calls per %.1f sec\n",Count,double(c2-c1)/CLK_TCK); } { c1=clock();
for (long i=0; i<Count; i++) for (long j=0; j<1000000; j++) f2();
c2=clock(); printf("f2(): %ld mlns calls per %.1f sec\n",Count,double(c2-c1)/CLK_TCK); } }
В ней функции f1() и f2() делают одно и то же, только первая неявно, с помощью конструктора и деструктора класса A, а вторая с помощью явного вызова ACon() и ADes().
Для работы программа требует одного параметра -- сколько миллионов раз вызывать тестовые функции. Выберите значение, позволяющее f1() работать несколько секунд и посмотрите на результат для f2().
При использовании качественного оптимизатора никакой разницы быть не должно; тем не менее, на некоторых платформах она определенно есть и порой достигает 10 раз!