homer512

Stack vs. Heap micro benchmark

Aug 10th, 2013
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.77 KB | None | 0 0
  1. #include <array>
  2. #include <vector>
  3. #include <utility>
  4. #include <chrono>
  5. #include <algorithm>
  6. #include <random>
  7. #include <cstdio>
  8.  
  9. #ifndef ARRAY_SIZE
  10. #  define ARRAY_SIZE 64
  11. #endif
  12. #ifndef LOOP_SIZE
  13. #  define LOOP_SIZE 64
  14. #endif
  15.  
  16. namespace {
  17.  
  18.   typedef std::chrono::high_resolution_clock clock;
  19.  
  20.   constexpr std::size_t array_n = ARRAY_SIZE;
  21.   constexpr std::size_t loop_n = LOOP_SIZE;
  22.  
  23.   template<class Container>
  24.   void init_container(Container& c)
  25.   {
  26.     for(std::size_t i = 0; i < c.size(); ++i)
  27.       c[i] = i;
  28.   }
  29.  
  30.   bool do_stack_alloc(int x)
  31.   {
  32.     std::array<int, array_n> stacked;
  33.     init_container(stacked);
  34.     return std::binary_search(stacked.begin(), stacked.end(), x);
  35.   }
  36.  
  37.   struct DoHeapAlloc
  38.   {
  39.     std::vector<int> heaped;
  40.     DoHeapAlloc():
  41.       heaped(array_n)
  42.     {
  43.       init_container(heaped);
  44.     }
  45.     DoHeapAlloc(const DoHeapAlloc&) = delete;
  46.     DoHeapAlloc(DoHeapAlloc&&) = default;
  47.     bool operator()(int x) const
  48.     {
  49.       return std::binary_search(heaped.begin(), heaped.end(), x);
  50.     }
  51.   };
  52.  
  53.   template<class Strategy>
  54.   bool test(const std::array<int, loop_n>& data, Strategy&& strategy)
  55.   {
  56.     bool res = false;
  57.     for(std::size_t i = 0; i < loop_n; ++i)
  58.       res ^= strategy(data[i]);
  59.     return res;
  60.   }
  61.  
  62.   template<class Strategy>
  63.   std::pair<clock::duration, bool> time(const std::array<int, loop_n>& data,
  64.                     Strategy&& strategy)
  65.   {
  66.     clock::time_point t = clock::now();
  67.     bool val = test(data, strategy);
  68.     clock::duration dt = clock::now() - t;
  69.     return std::make_pair(dt, val);
  70.   }
  71.  
  72.   void make_test_data(std::array<int, loop_n>& data)
  73.   {
  74.     std::default_random_engine generator;
  75.     std::uniform_int_distribution<int> distribution(0, 2 * array_n);
  76.     for(std::size_t i = 0; i < data.size(); ++i)
  77.       data[i] = distribution(generator);
  78.   }
  79.  
  80.   template<class Strategy1, class Strategy2>
  81.   void compare(Strategy1&& s1, Strategy2&& s2, const char* s1_name,
  82.            const char* s2_name)
  83.   {
  84.     std::array<int, loop_n> data;
  85.     make_test_data(data);
  86.     std::array<std::pair<clock::duration, bool>, 4> out;
  87.     out[0] = time(data, s1);
  88.     out[1] = time(data, s2);
  89.     out[2] = time(data, s1);
  90.     out[3] = time(data, s2);
  91.     if(out[0].second != out[1].second)
  92.       std::printf("Strategies not equivalent\n");
  93.     else if(out[0].first == out[1].first)
  94.       std::printf("Cannot distinguish strategies\n");
  95.     else if((out[0].first < out[1].first) != (out[2].first < out[3].first))
  96.       std::printf("Performance depends on execution order\n");
  97.     else
  98.       std::printf("%s is faster\n", out[0].first < out[1].first ?
  99.           s1_name : s2_name);
  100.   }
  101. }
  102.  
  103. int main()
  104. {
  105.   compare(do_stack_alloc, DoHeapAlloc(), "stack allocation", "heap allocation");
  106.   return 0;
  107. }
Advertisement
Add Comment
Please, Sign In to add comment