diff --git a/dune/perftool/common/opcounter.hh b/dune/perftool/common/opcounter.hh
new file mode 100644
index 0000000000000000000000000000000000000000..8d80f2bdf6801d285b122ee9fe77b17c5da25a53
--- /dev/null
+++ b/dune/perftool/common/opcounter.hh
@@ -0,0 +1,863 @@
+#ifndef __OPCOUNTER__
+#define __OPCOUNTER__
+
+#include <type_traits>
+#include <iostream>
+#include <cmath>
+#include <cstdlib>
+
+namespace oc {
+
+  template<typename F>
+  class OpCounter;
+
+}
+
+namespace Dune {
+
+  template<typename T, int n>
+  class FieldVector;
+
+}
+
+namespace oc {
+
+  template<typename F>
+  class OpCounter
+  {
+
+  public:
+
+    typedef std::size_t size_type;
+
+    using value_type = F;
+
+    OpCounter()
+      : _v()
+    {}
+
+    template<typename T>
+    OpCounter(const T& t, typename std::enable_if<std::is_same<T,int>::value and !std::is_same<F,int>::value>::type* = nullptr)
+      : _v(t)
+    {}
+
+    OpCounter(const F& f)
+      : _v(f)
+    {}
+
+    OpCounter(F&& f)
+      : _v(f)
+    {}
+
+    explicit OpCounter(const char* s)
+      : _v(strtod(s,nullptr))
+    {}
+
+    OpCounter& operator=(const char* s)
+    {
+      _v = strtod(s,nullptr);
+      return *this;
+    }
+
+    explicit operator F() const
+    {
+      return _v;
+    }
+
+    OpCounter& operator=(const F& f)
+    {
+      _v = f;
+      return *this;
+    }
+
+    OpCounter& operator=(F&& f)
+    {
+      _v = f;
+      return *this;
+    }
+
+    friend std::ostream& operator<<(std::ostream& os, const OpCounter& f)
+    {
+      os << "OC(" << f._v << ")";
+      return os;
+    }
+
+    friend std::istringstream& operator>>(std::istringstream& iss, OpCounter& f)
+    {
+      iss >> f._v;
+      return iss;
+    }
+
+    F* data()
+    {
+      return &_v;
+    }
+
+    const F* data() const
+    {
+      return &_v;
+    }
+
+    F _v;
+
+    struct Counters {
+
+      size_type addition_count;
+      size_type multiplication_count;
+      size_type division_count;
+      size_type exp_count;
+      size_type pow_count;
+      size_type sin_count;
+      size_type sqrt_count;
+      size_type comparison_count;
+
+      Counters()
+        : addition_count(0)
+        , multiplication_count(0)
+        , division_count(0)
+        , exp_count(0)
+        , pow_count(0)
+        , sin_count(0)
+        , sqrt_count(0)
+        , comparison_count(0)
+      {}
+
+      void reset()
+      {
+        addition_count = 0;
+        multiplication_count = 0;
+        division_count = 0;
+        exp_count = 0;
+        pow_count = 0;
+        sin_count = 0;
+        sqrt_count = 0;
+        comparison_count = 0;
+      }
+
+      template<typename Stream>
+      void reportOperations(Stream& os, bool doReset = false)
+      {
+        os << "additions: " << addition_count << std::endl
+           << "multiplications: " << multiplication_count << std::endl
+           << "divisions: " << division_count << std::endl
+           << "exp: " << exp_count << std::endl
+           << "pow: " << pow_count << std::endl
+           << "sin: " << sin_count << std::endl
+           << "sqrt: " << sqrt_count << std::endl
+           << "comparisons: " << comparison_count << std::endl
+           << std::endl
+           << "total: " << addition_count + multiplication_count + division_count + exp_count + pow_count + sin_count + sqrt_count + comparison_count << std::endl;
+
+        if (doReset)
+          reset();
+      }
+
+      Counters& operator+=(const Counters& rhs)
+      {
+        addition_count += rhs.addition_count;
+        multiplication_count += rhs.multiplication_count;
+        division_count += rhs.division_count;
+        exp_count += rhs.exp_count;
+        pow_count += rhs.pow_count;
+        sin_count += rhs.sin_count;
+        sqrt_count += rhs.sqrt_count;
+        comparison_count += rhs.comparison_count;
+        return *this;
+      }
+
+      Counters operator-(const Counters& rhs)
+      {
+        Counters r;
+        r.addition_count = addition_count - rhs.addition_count;
+        r.multiplication_count = multiplication_count - rhs.multiplication_count;
+        r.division_count = division_count - rhs.division_count;
+        r.exp_count = exp_count - rhs.exp_count;
+        r.pow_count = pow_count - rhs.pow_count;
+        r.sin_count = sin_count - rhs.sin_count;
+        r.sqrt_count = sqrt_count - rhs.sqrt_count;
+        r.comparison_count = comparison_count - rhs.comparison_count;
+        return r;
+      }
+
+    };
+
+    static void additions(std::size_t n)
+    {
+      counters.addition_count += n;
+    }
+
+    static void multiplications(std::size_t n)
+    {
+      counters.multiplication_count += n;
+    }
+
+    static void divisions(std::size_t n)
+    {
+      counters.division_count += n;
+    }
+
+    static void reset()
+    {
+      counters.reset();
+    }
+
+    template<typename Stream>
+    static void reportOperations(Stream& os, bool doReset = false)
+    {
+      counters.reportOperations(os,doReset);
+    }
+
+    static Counters counters;
+
+  };
+
+  template<typename F>
+  typename OpCounter<F>::Counters OpCounter<F>::counters;
+
+  // ********************************************************************************
+  // negation
+  // ********************************************************************************
+
+  template<typename F>
+  OpCounter<F> operator-(const OpCounter<F>& a)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {-a._v};
+  }
+
+
+  // ********************************************************************************
+  // addition
+  // ********************************************************************************
+
+  template<typename F>
+  OpCounter<F> operator+(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {a._v + b._v};
+  }
+
+  template<typename F>
+  OpCounter<F> operator+(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {a._v + b};
+  }
+
+  template<typename F>
+  OpCounter<F> operator+(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {a + b._v};
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>
+    >::type
+  operator+(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {a._v + b};
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>
+    >::type
+  operator+(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {a + b._v};
+  }
+
+  template<typename F>
+  OpCounter<F>& operator+=(OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    a._v += b._v;
+    return a;
+  }
+
+  template<typename F>
+  OpCounter<F>& operator+=(OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    a._v += b;
+    return a;
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>&
+    >::type
+  operator+=(OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    a._v += b;
+    return a;
+  }
+
+  template<typename F>
+  OpCounter<F>& operator+=(OpCounter<F>& a, const Dune::FieldVector<OpCounter<F>,1>& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    a._v += b[0]._v;
+    return a;
+  }
+
+  // ********************************************************************************
+  // subtraction
+  // ********************************************************************************
+
+  template<typename F>
+  OpCounter<F> operator-(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {a._v - b._v};
+  }
+
+  template<typename F>
+  OpCounter<F> operator-(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {a._v - b};
+  }
+
+  template<typename F>
+  OpCounter<F> operator-(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {a - b._v};
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>
+    >::type
+  operator-(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {a._v - b};
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>
+    >::type
+  operator-(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    return {a - b._v};
+  }
+
+  template<typename F>
+  OpCounter<F>& operator-=(OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    a._v -= b._v;
+    return a;
+  }
+
+  template<typename F>
+  OpCounter<F>& operator-=(OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    a._v -= b;
+    return a;
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>&
+    >::type
+  operator-=(OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.addition_count;
+    a._v -= b;
+    return a;
+  }
+
+
+  // ********************************************************************************
+  // multiplication
+  // ********************************************************************************
+
+  template<typename F>
+  OpCounter<F> operator*(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.multiplication_count;
+    return {a._v * b._v};
+  }
+
+  template<typename F>
+  OpCounter<F> operator*(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.multiplication_count;
+    return {a._v * b};
+  }
+
+  template<typename F>
+  OpCounter<F> operator*(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.multiplication_count;
+    return {a * b._v};
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>
+    >::type
+  operator*(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.multiplication_count;
+    return {a._v * b};
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>
+    >::type
+  operator*(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.multiplication_count;
+    return {a * b._v};
+  }
+
+  template<typename F>
+  OpCounter<F>& operator*=(OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.multiplication_count;
+    a._v *= b._v;
+    return a;
+  }
+
+  template<typename F>
+  OpCounter<F>& operator*=(OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.multiplication_count;
+    a._v *= b;
+    return a;
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>&
+    >::type
+  operator*=(OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.multiplication_count;
+    a._v *= b;
+    return a;
+  }
+
+
+  // ********************************************************************************
+  // division
+  // ********************************************************************************
+
+  template<typename F>
+  OpCounter<F> operator/(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.division_count;
+    return {a._v / b._v};
+  }
+
+  template<typename F>
+  OpCounter<F> operator/(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.division_count;
+    return {a._v / b};
+  }
+
+  template<typename F>
+  OpCounter<F> operator/(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.division_count;
+    return {a / b._v};
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>
+    >::type
+  operator/(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.division_count;
+    return {a._v / b};
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>
+    >::type
+  operator/(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.division_count;
+    return {a / b._v};
+  }
+
+  template<typename F>
+  OpCounter<F>& operator/=(OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.division_count;
+    a._v /= b._v;
+    return a;
+  }
+
+  template<typename F>
+  OpCounter<F>& operator/=(OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.division_count;
+    a._v /= b;
+    return a;
+  }
+
+  template<typename F, typename T>
+  typename std::enable_if<
+    std::is_arithmetic<T>::value,
+    OpCounter<F>&
+    >::type
+  operator/=(OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.division_count;
+    a._v /= b;
+    return a;
+  }
+
+
+
+  // ********************************************************************************
+  // comparisons
+  // ********************************************************************************
+
+
+  // ********************************************************************************
+  // less
+  // ********************************************************************************
+
+  template<typename F>
+  bool operator<(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v < b._v};
+  }
+
+  template<typename F>
+  bool operator<(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v < b};
+  }
+
+  template<typename F>
+  bool operator<(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a < b._v};
+  }
+
+  template<typename F, typename T>
+  bool operator<(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v < b};
+  }
+
+  template<typename F, typename T>
+  bool operator<(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a < b._v};
+  }
+
+
+  // ********************************************************************************
+  // less_or_equals
+  // ********************************************************************************
+
+  template<typename F>
+  bool operator<=(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v <= b._v};
+  }
+
+  template<typename F>
+  bool operator<=(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v <= b};
+  }
+
+  template<typename F>
+  bool operator<=(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a <= b._v};
+  }
+
+  template<typename F, typename T>
+  bool operator<=(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v <= b};
+  }
+
+  template<typename F, typename T>
+  bool operator<=(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a <= b._v};
+  }
+
+
+  // ********************************************************************************
+  // greater
+  // ********************************************************************************
+
+  template<typename F>
+  bool operator>(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v > b._v};
+  }
+
+  template<typename F>
+  bool operator>(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v > b};
+  }
+
+  template<typename F>
+  bool operator>(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a > b._v};
+  }
+
+  template<typename F, typename T>
+  bool operator>(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v > b};
+  }
+
+  template<typename F, typename T>
+  bool operator>(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a > b._v};
+  }
+
+
+  // ********************************************************************************
+  // greater_or_equals
+  // ********************************************************************************
+
+  template<typename F>
+  bool operator>=(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v >= b._v};
+  }
+
+  template<typename F>
+  bool operator>=(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v >= b};
+  }
+
+  template<typename F>
+  bool operator>=(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a >= b._v};
+  }
+
+  template<typename F, typename T>
+  bool operator>=(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v >= b};
+  }
+
+  template<typename F, typename T>
+  bool operator>=(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a >= b._v};
+  }
+
+
+  // ********************************************************************************
+  // inequals
+  // ********************************************************************************
+
+  template<typename F>
+  bool operator!=(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v != b._v};
+  }
+
+  template<typename F>
+  bool operator!=(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v != b};
+  }
+
+  template<typename F>
+  bool operator!=(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a != b._v};
+  }
+
+  template<typename F, typename T>
+  bool operator!=(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v != b};
+  }
+
+  template<typename F, typename T>
+  bool operator!=(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a != b._v};
+  }
+
+
+  // ********************************************************************************
+  // equals
+  // ********************************************************************************
+
+  template<typename F>
+  bool operator==(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v == b._v};
+  }
+
+  template<typename F>
+  bool operator==(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v == b};
+  }
+
+  template<typename F>
+  bool operator==(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a == b._v};
+  }
+
+  template<typename F, typename T>
+  bool operator==(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a._v == b};
+  }
+
+  template<typename F, typename T>
+  bool operator==(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {a == b._v};
+  }
+
+
+
+  // ********************************************************************************
+  // functions
+  // ********************************************************************************
+
+  template<typename F>
+  OpCounter<F> exp(const OpCounter<F>& a)
+  {
+    ++OpCounter<F>::counters.exp_count;
+    return {std::exp(a._v)};
+  }
+
+  template<typename F>
+  OpCounter<F> pow(const OpCounter<F>& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.pow_count;
+    return {std::pow(a._v,b._v)};
+  }
+
+  template<typename F>
+  OpCounter<F> pow(const OpCounter<F>& a, const F& b)
+  {
+    ++OpCounter<F>::counters.pow_count;
+    return {std::pow(a._v,b)};
+  }
+
+  template<typename F, typename T>
+  OpCounter<F> pow(const OpCounter<F>& a, const T& b)
+  {
+    ++OpCounter<F>::counters.pow_count;
+    return {std::pow(a._v,b)};
+  }
+
+  template<typename F>
+  OpCounter<F> pow(const F& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.pow_count;
+    return {std::pow(a,b._v)};
+  }
+
+  template<typename F, typename T>
+  OpCounter<F> pow(const T& a, const OpCounter<F>& b)
+  {
+    ++OpCounter<F>::counters.pow_count;
+    return {std::pow(a,b._v)};
+  }
+
+  template<typename F>
+  OpCounter<F> sin(const OpCounter<F>& a)
+  {
+    ++OpCounter<F>::counters.sin_count;
+    return {std::sin(a._v)};
+  }
+
+  template<typename F>
+  OpCounter<F> cos(const OpCounter<F>& a)
+  {
+    ++OpCounter<F>::counters.sin_count;
+    return {std::cos(a._v)};
+  }
+
+  template<typename F>
+  OpCounter<F> sqrt(const OpCounter<F>& a)
+  {
+    ++OpCounter<F>::counters.sqrt_count;
+    return {std::sqrt(a._v)};
+  }
+
+  template<typename F>
+  OpCounter<F> abs(const OpCounter<F>& a)
+  {
+    ++OpCounter<F>::counters.comparison_count;
+    return {std::abs(a._v)};
+  }
+
+}
+
+#endif // __OPCOUNTER__
diff --git a/dune/perftool/common/timer.hh b/dune/perftool/common/timer.hh
new file mode 100644
index 0000000000000000000000000000000000000000..890a8b45edbcb122bb7d2a0fe2c1ada8c4207467
--- /dev/null
+++ b/dune/perftool/common/timer.hh
@@ -0,0 +1,71 @@
+#ifndef HP_TIMER_HH
+#define HP_TIMER_HH
+
+#include <chrono>
+
+# include <dune/perftool/common/opcounter.hh>
+
+#define HP_TIMER_OPCOUNTER oc::OpCounter<double>
+
+#define HP_TIMER_DURATION(name) __hp_timer_##name##_duration
+#define HP_TIMER_STARTTIME(name) __hp_timer_##name##_start
+#define HP_TIMER_OPCOUNTERS_START(name) __hp_timer_##name##_counters_start
+#define HP_TIMER_OPCOUNTERS(name) __hp_timer_##name##_counters
+#define HP_TIMER_ELAPSED(name) std::chrono::duration_cast<std::chrono::duration<double> >( HP_TIMER_DURATION(name) ).count()
+
+#ifdef ENABLE_HP_TIMERS
+
+#ifdef ENABLE_COUNTER
+
+#define HP_DECLARE_TIMER(name)                               \
+  std::chrono::high_resolution_clock::duration HP_TIMER_DURATION(name);	\
+  std::chrono::high_resolution_clock::time_point HP_TIMER_STARTTIME(name); \
+  HP_TIMER_OPCOUNTER::Counters HP_TIMER_OPCOUNTERS_START(name); \
+  HP_TIMER_OPCOUNTER::Counters HP_TIMER_OPCOUNTERS(name);
+
+#define HP_TIMER_START(name) \
+  do { \
+  HP_TIMER_OPCOUNTERS_START(name) = HP_TIMER_OPCOUNTER::counters; \
+  HP_TIMER_STARTTIME(name) = std::chrono::high_resolution_clock::now(); \
+  } while(false)
+
+#define HP_TIMER_STOP(name) \
+  do { \
+  std::chrono::high_resolution_clock::time_point __hp_end_time = std::chrono::high_resolution_clock::now(); \
+  HP_TIMER_OPCOUNTERS(name) += HP_TIMER_OPCOUNTER::counters - HP_TIMER_OPCOUNTERS_START(name); \
+  HP_TIMER_DURATION(name) += __hp_end_time - HP_TIMER_STARTTIME(name); \
+  } while(false)
+
+#define HP_TIMER_RESET(name) \
+  do { \
+    HP_TIMER_DURATION(name) = std::chrono::high_resolution_clock::duration::zero(); \
+  HP_TIMER_OPCOUNTERS(name).reset(); \
+  } while (false)
+
+#else
+
+#define HP_DECLARE_TIMER(name)                               \
+  std::chrono::high_resolution_clock::duration HP_TIMER_DURATION(name);	\
+  std::chrono::high_resolution_clock::time_point HP_TIMER_STARTTIME(name);
+
+#define HP_TIMER_START(name) HP_TIMER_STARTTIME(name) = std::chrono::high_resolution_clock::now();
+#define HP_TIMER_STOP(name) \
+  do { \
+  std::chrono::high_resolution_clock::time_point __hp_end_time = std::chrono::high_resolution_clock::now(); \
+  HP_TIMER_DURATION(name) += __hp_end_time - HP_TIMER_STARTTIME(name); \
+  } while(false)
+
+#define HP_TIMER_RESET(name) HP_TIMER_DURATION(name) = std::chrono::high_resolution_clock::duration::zero();
+
+#endif // ENABLE_COUNTER
+
+#else // ENABLE_HP_TIMERS
+
+#define HP_DECLARE_TIMER(name)
+#define HP_TIMER_START(name)
+#define HP_TIMER_STOP(name)
+#define HP_TIMER_RESET(name)
+
+#endif // ENABLE_HP_TIMERS
+
+#endif // HP_TIMER_HH
diff --git a/python/dune/perftool/file.py b/python/dune/perftool/file.py
index e5abbaed55e0e12fce92ceb74e59b693f078127f..3fcd033591a7b1f23f0cbcaee237869f0d549c5a 100644
--- a/python/dune/perftool/file.py
+++ b/python/dune/perftool/file.py
@@ -26,8 +26,14 @@ def generate_file(filename, tag, content, headerguard=True):
             macro = filename.upper().replace("/", "_").replace(".", "_").replace("-", "_")
             f.write("#ifndef {0}\n#define {0}\n\n".format(macro))
 
-        # Add the includes from the cache
         from dune.perftool.generation import retrieve_cache_items
+        # Add pre include lines from the cache
+        for define in retrieve_cache_items('{} and pre_include'.format(tag)):
+            for line in define:
+                f.write(line)
+            f.write('\n')
+
+        # Add the includes from the cache
         for inc in retrieve_cache_items('{} and include'.format(tag)):
             from cgen import Include
             assert isinstance(inc, Include)
@@ -35,6 +41,12 @@ def generate_file(filename, tag, content, headerguard=True):
                 f.write(line)
             f.write('\n')
 
+        # Add post include lines from the cache
+        for define in retrieve_cache_items('{} and post_include'.format(tag)):
+            for line in define:
+                f.write(line)
+            f.write('\n')
+
         f.write('\n\n')
 
         for c in content:
diff --git a/python/dune/perftool/generation/__init__.py b/python/dune/perftool/generation/__init__.py
index 5edd83582410e7e70730b0ff2db3ab75efb42328..cd2779b301ac75532f5dd59d3e73ea65cbaa971d 100644
--- a/python/dune/perftool/generation/__init__.py
+++ b/python/dune/perftool/generation/__init__.py
@@ -15,7 +15,9 @@ from dune.perftool.generation.cpp import (base_class,
                                           constructor_parameter,
                                           include_file,
                                           initializer_list,
+                                          pre_include,
                                           preamble,
+                                          post_include,
                                           symbol,
                                           template_parameter,
                                           )
diff --git a/python/dune/perftool/generation/cpp.py b/python/dune/perftool/generation/cpp.py
index c23550a13b2714bea08c7404f932d8ab96f667f7..70735c65dd33abd623f3f9a4d5b2dd1b4008c3b6 100644
--- a/python/dune/perftool/generation/cpp.py
+++ b/python/dune/perftool/generation/cpp.py
@@ -10,6 +10,18 @@ symbol = generator_factory(item_tags=("symbol",))
 preamble = generator_factory(item_tags=("preamble",), counted=True)
 
 
+def pre_include(pre, filetag=None, pre_include=True):
+    assert filetag
+    gen = generator_factory(item_tags=("file", filetag, "pre_include"), no_deco=True)
+    return gen(pre)
+
+
+def post_include(post, filetag=None, pre_include=True):
+    assert filetag
+    gen = generator_factory(item_tags=("file", filetag, "post_include"), no_deco=True)
+    return gen(post)
+
+
 def include_file(include, filetag=None):
     assert filetag
     from cgen import Include
diff --git a/python/dune/perftool/options.py b/python/dune/perftool/options.py
index 5441bb4714710297acb00803ec5543ecb55b5d9f..85fd6304c051f94e51f1679404445c7776c1bee9 100644
--- a/python/dune/perftool/options.py
+++ b/python/dune/perftool/options.py
@@ -34,6 +34,7 @@ def get_form_compiler_arguments():
     parser.add_argument("--print-transformations-dir", type=str, help="place where to put dot files (can be omitted)")
     parser.add_argument("--diagonal-transformation-matrix", action="store_true", help="set option if the jacoby of the transformation is diagonal (axiparallel grids)")
     parser.add_argument("--ini-file", type=str, help="An inifile to use. A generated driver will be hard-coded to it, a [formcompiler] section will be used as default values to form compiler arguments (use snake case)")
+    parser.add_argument("--timer", action="store_true", help="measure times")
 
     # Modify the positional argument to not be a list
     args = vars(parser.parse_args())
diff --git a/python/dune/perftool/pdelab/driver.py b/python/dune/perftool/pdelab/driver.py
index cb786db5ed2ad1e87cf8f68ce002479d67a26751..3bca95f288a6d96560318d4c675b8e141fa8a23a 100644
--- a/python/dune/perftool/pdelab/driver.py
+++ b/python/dune/perftool/pdelab/driver.py
@@ -1091,24 +1091,41 @@ def dune_solve():
     # Test wether we want to do matrix free operator evaluation
     matrix_free = get_option('matrix_free')
 
+    # Get right solve command
     if linear and matrix_free:
         formdata = _driver_data['formdata']
         go = name_gridoperator(formdata)
         x = name_vector(formdata)
         include_file("dune/perftool/matrixfree.hh", filetag="driver")
-        return "solveMatrixFree({},{});".format(go, x)
+        solve = "solveMatrixFree({},{});".format(go, x)
     elif linear and not matrix_free:
         slp = name_stationarylinearproblemsolver()
-        return "{}.apply();".format(slp)
+        solve = "{}.apply();".format(slp)
     elif not linear and matrix_free:
         raise NotImplementedError("Nonlinear and matrix free is not yet implemented")
     elif not linear and not matrix_free:
         go_type = type_gridoperator(_driver_data['formdata'])
         go = name_gridoperator(_driver_data['formdata'])
         snp = name_stationarynonlinearproblemsolver(go_type, go)
-        return "{}.apply();".format(snp)
-    else:
-        assert False
+        solve = "{}.apply();".format(snp)
+
+    timer = get_option('timer')
+    if timer:
+        from dune.perftool.generation import pre_include
+        from dune.perftool.generation import post_include
+        pre_include("#define ENABLE_HP_TIMERS", filetag="driver")
+        include_file("dune/perftool/common/timer.hh", filetag="driver")
+        post_include("HP_DECLARE_TIMER(total);", filetag="driver")
+        solve = ["HP_TIMER_START(total);",
+                 "{}".format(solve),
+                 "HP_TIMER_STOP(total);",
+                 "",
+                 "// Print timer results",
+                 "std::cout << std::endl;",
+                 "std::cout << \"===== total =====\" << std::endl;",
+                 "std::cout << \"timer elapsed: \" << HP_TIMER_ELAPSED(total) << std::endl;"]
+
+    return solve
 
 
 @preamble
diff --git a/test/poisson/poisson.mini b/test/poisson/poisson.mini
index eb8c175b6a9b09da89b11ee244978c4099ede35e..71c3cda88f974cf11ef4edcf35320e3f1fbcf6bd 100644
--- a/test/poisson/poisson.mini
+++ b/test/poisson/poisson.mini
@@ -13,3 +13,4 @@ extension = vtu
 
 [formcompiler]
 numerical_jacobian = 1, 0 | expand num
+timer = 1
\ No newline at end of file