Advertisement
Guest User

dynamic_cast versus typeid: benchmark code

a guest
Jun 27th, 2017
880
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.80 KB | None | 0 0
  1. #include <typeinfo>
  2. #include <vector>
  3. #include <benchmark/benchmark.h>
  4.  
  5. struct Base {
  6.   virtual ~Base() { }
  7.   virtual int id() const = 0;
  8. };
  9.  
  10. template <class T> struct Id;
  11.  
  12. template<> struct Id<int> { static const int value = 1; };
  13. template<> struct Id<float> { static const int value = 2; };
  14. template<> struct Id<char> { static const int value = 3; };
  15. template<> struct Id<unsigned long> { static const int value = 4; };
  16.  
  17. template <class T>
  18. struct Derived : Base {
  19.     virtual int id() const { return Id<T>::value; }
  20. };
  21.  
  22. int test1(std::vector<Base *>& v)
  23. {
  24.     int total = 0;
  25.     for (Base *bp : v) {
  26.         if (Derived<int>* dp = dynamic_cast<Derived<int>*>(bp)) {
  27.             total += 5;
  28.         } else if (Derived<float> *dp = dynamic_cast<Derived<float>*>(bp)) {
  29.             total += 7;
  30.         } else if (Derived<char> *dp = dynamic_cast<Derived<char>*>(bp)) {
  31.             total += 2;
  32.         } else if (Derived<unsigned long> *dp = dynamic_cast<Derived<unsigned long>*>(bp)) {
  33.             total += 9;
  34.         }
  35.     }
  36.     return total;
  37. }
  38.  
  39. int test2(std::vector<Base *>& v)
  40. {
  41.     int total = 0;
  42.     for (Base *bp : v) {
  43.         const std::type_info& type = typeid(*bp);
  44.         if (type==typeid(Derived<int>)) {
  45.             total += 5;
  46.         } else if (type==typeid(Derived<float>)) {
  47.             total += 7;
  48.         } else if (type==typeid(Derived<char>)) {
  49.             total += 2;
  50.         } else if (type==typeid(Derived<unsigned long>)) {
  51.             total += 9;
  52.         }
  53.     }
  54.     return total;
  55. }
  56.  
  57. int test3(std::vector<Base *>& v)
  58. {
  59.     int total = 0;
  60.     for (Base *bp : v) {
  61.         int id = bp->id();
  62.         switch (id) {
  63.             case 1: total += 5; break;
  64.             case 2: total += 7; break;
  65.             case 3: total += 2; break;
  66.             case 4: total += 9; break;
  67.         }
  68.     }
  69.     return total;
  70. }
  71.  
  72. Base *new_random_subclass() {
  73.     switch (rand() % 4) {
  74.         case 0: return new Derived<int>;
  75.         case 1: return new Derived<float>;
  76.         case 2: return new Derived<char>;
  77.         default: return new Derived<unsigned long>;
  78.     }
  79. }
  80.  
  81. template<int(&f)(std::vector<Base *>&)>
  82. void bench(benchmark::State& state) {
  83.     std::vector<Base *> v(1000);
  84.     while (state.KeepRunning()) {
  85.         state.PauseTiming();
  86.         for (int i=0; i < 1000; ++i) {
  87.             v[i] = new_random_subclass();
  88.         }
  89.         state.ResumeTiming();
  90.         int result = f(v);
  91.         benchmark::DoNotOptimize(result);
  92.     }
  93. }
  94.  
  95. void bench_dynamic_cast(benchmark::State& state) { bench<test1>(state); }
  96. void bench_typeid(benchmark::State& state) { bench<test2>(state); }
  97. void bench_id_method(benchmark::State& state) { bench<test3>(state); }
  98.  
  99.  
  100. BENCHMARK(bench_dynamic_cast);
  101. BENCHMARK(bench_typeid);
  102. BENCHMARK(bench_id_method);
  103. BENCHMARK_MAIN();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement