Mach7 benchmark

#include <boost/variant.hpp>
#include <mach7/type_switchN-patterns-xtl.hpp>
#include <mach7/adapters/boost/adapt_boost_variant.hpp>
#include <mach7/patterns/constructor.hpp>
 
#include <ctime>
#include <iostream>
#include <vector>
 
struct P { int i; };
struct Q { int i; };
struct R { int i; };
 
struct M { int i; };
struct N { int i; };
 
typedef boost::variant<P, Q, R> VP;
typedef boost::variant<M, N> VM;
 
int g_pm = 0;
int g_qm = 0;
int g_rm = 0;
int g_pn = 0;
int g_qn = 0;
int g_rn = 0;
 
void count_with_mach7(VP const& vp, VM const& vm)
{
  using mch::C;
   
  Match(vp, vm)
  {
    Case(C<P>(), C<M>()) ++g_pm; break;
    Case(C<Q>(), C<M>()) ++g_qm; break;
    Case(C<R>(), C<M>()) ++g_rm; break;
    Case(C<P>(), C<N>()) ++g_pn; break;
    Case(C<Q>(), C<N>()) ++g_qn; break;
    Case(C<R>(), C<N>()) ++g_rn; break;
  }
  EndMatch
}
 
void count_with_visitor(VP const& vp, VM const& vm)
{
  struct increment : boost::static_visitor<>
  {
    void operator()(const P&, const M&) const { ++g_pm; }
    void operator()(const Q&, const M&) const { ++g_qm; }
    void operator()(const R&, const M&) const { ++g_rm; }
    void operator()(const P&, const N&) const { ++g_pn; }
    void operator()(const Q&, const N&) const { ++g_qn; }
    void operator()(const R&, const N&) const { ++g_rn; }
  };
   
  apply_visitor(increment{}, vp, vm);
}
 
struct result
{
  clock_t mach7;
  clock_t visit;
};
 
result measure(const std::vector<VP>& vecp,
               const std::vector<VM>& vecm,
               const bool mach7_first)
{
  result ans{};
   
  if (mach7_first)
  {
    clock_t t0 = clock();
    for (const VP& vp : vecp) for (const VM& vm : vecm)
      count_with_mach7(vp, vm);
    clock_t t1 = clock();
    ans.mach7 = (t1 - t0);
  }
   
  {
    clock_t t0 = clock();
    for (const VP& vp : vecp) for (const VM& vm : vecm)
      count_with_visitor(vp, vm);
    clock_t t1 = clock();
    ans.visit = (t1 - t0);
  }
   
  if (!mach7_first)
  {
    clock_t t0 = clock();
    for (const VP& vp : vecp) for (const VM& vm : vecm)
      count_with_mach7(vp, vm);
    clock_t t1 = clock();
    ans.mach7 = (t1 - t0);
  }
   
  return ans;
}
 
void populate_data(std::vector<VP>& vec_vp, 
                   std::vector<VM>& vec_vm,
                   const int SIZE)
{
  vec_vm.reserve(SIZE);
  vec_vp.reserve(SIZE);
   
  for(int i = 0; i != SIZE; ++i) {
    if (i % 3 == 0)
      vec_vp.push_back(P{0});
    else if (i % 3 == 1)
      vec_vp.push_back(Q{0});
    else
      vec_vp.push_back(R{0});
       
    if (i % 2 == 0)
      vec_vm.push_back(M{0});
    else
      vec_vm.push_back(N{0});
  }
}
 
const int DATA_SIZE = 10000;
const int TEST_NUM = 8;
 
int main()
{
  std::vector<VP> vec_vp;
  std::vector<VM> vec_vm;
  populate_data(vec_vp, vec_vm, DATA_SIZE);
   
  std::vector<result> results;
  for (int i = 0; i < TEST_NUM; i += 2) {
    results.push_back(measure(vec_vp, vec_vm, true));
    results.push_back(measure(vec_vp, vec_vm, false));
  }
   
  std::cout << "mach7" "\t" "visit" << std::endl;
  for (const result& r : results)
    std::cout << r.mach7 << "\t" << r.visit << std::endl;
}

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.