четверг, 12 сентября 2013 г.

О влиянии исключений на производительность в C++

Несколько лет назад я сравнивал производительность кода, использующего Exceptions в .NET, и кода, работающего в обход такой обработки. Результаты опубликовывал здесь. Как видим, разница была колоссальная: 5мин. 30 сек., против 0,7 сек. К сожалению, в C++ обработка исключений так же является весьма накладным занятием...



Желание сравнить результаты обусловлено информацией, предоставленной Александром Ривилисом:
В C/C++ исключения генерируются крайне редко. А в Win32 API практически никогда.
...
Обработка исключений очень расходная операция. Не только в .NET но и в C++. Я использую исключения поминимуму. Только если нужно в случае ошибки выйти из глубокой цепочки вызовов функций. 
Написал простой тестовый код:


   1:  #include <iostream>
   2:  #include <string>
   3:  #include <exception>
   4:  #include <ctime>
   5:   
   6:  using namespace ::std;
   7:   
   8:  int main()
   9:  try{
  10:      int max_count = 0;
  11:      cout << "Get iterations max count: ";
  12:      cin >> max_count;
  13:      void without_exceptions(int);
  14:      void through_exceptions(int);
  15:      
  16:      without_exceptions(max_count);
  17:      through_exceptions(max_count);
  18:  }
  19:  catch(exception& e){
  20:      cerr << e.what() << endl;
  21:      return 1;
  22:  }
  23:  catch(...){
  24:      cerr << "Unknown exception." << endl;
  25:      return 2;
  26:  }
  27:   
  28:  void without_exceptions(int max_count){
  29:          clock_t cur_time1 = clock();
  30:      for(int i = 0; i < max_count; ++i){        
  31:          if(i >= 0);
  32:      }
  33:      clock_t cur_time2 = clock();
  34:      double secs = double(cur_time2-cur_time1)/double(CLOCKS_PER_SEC);
  35:      cout << "without_exceptions = " << secs << "sec." << endl;
  36:  }
  37:   
  38:  void through_exceptions(int max_count){
  39:      clock_t cur_time1 = clock();
  40:      for(int i = 0; i < max_count; ++i){        
  41:          try{
  42:              if(i >= 0) throw runtime_error("");
  43:          }
  44:          catch(runtime_error& e){}
  45:      }
  46:      clock_t cur_time2 = clock();
  47:      double secs = double(cur_time2-cur_time1)/double(CLOCKS_PER_SEC);
  48:      cout << "through_exceptions = " << secs << "sec." << endl;
  49:  }

Результаты работы кода следующие:

c:\src>speed_test.exe
Get iterations max count: 100000
without_exceptions = 0sec.
through_exceptions = 0.347sec.

c:\src>speed_test.exe
Get iterations max count: 1000000
without_exceptions = 0.004sec.
through_exceptions = 2.931sec.

c:\src>speed_test.exe
Get iterations max count: 10000000
without_exceptions = 0.044sec.
through_exceptions = 29.071sec.

Как видим, в C++ обработка исключений так же является весьма затратным делом (к сожалению)... :(((

P.S. Любопытная статья по теме здесь.

Комментариев нет: