summaryrefslogtreecommitdiff
path: root/libs/math/performance/performance_measure.hpp
blob: ce192dee64da8b6484f69b0df62e379c5519f079 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//  Copyright John Maddock 2007.
//  Use, modification and distribution are subject to the
//  Boost Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_MATH_PERFORMANCE_MEASURE_HPP
#define BOOST_MATH_PERFORMANCE_MEASURE_HPP

#include <boost/config.hpp>
#include <boost/timer.hpp>
#include <cstring>

#ifdef _WIN32
#include <windows.h>
#endif

template <class F>
double performance_measure(F f)
{
   unsigned count = 1;
   double time, result;
#ifdef _WIN32
   int old_priority = GetThreadPriority(GetCurrentThread());
   SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
#endif
   //
   // Begin by figuring out how many times to repeat
   // the function call in order to get a measureable time:
   //
   do
   {
      boost::timer t;
      for(unsigned i = 0; i < count; ++i)
         f();
      time = t.elapsed();
      count *= 2;
      t.restart();
   }while(time < 0.5);

   count /= 2;
   result = time;
   //
   // Now repeat the measurement over and over
   // and take the shortest measured time as the
   // result, generally speaking this gives us
   // consistent results:
   //
   for(unsigned i = 0; i < 20u;++i)
   {
      boost::timer t;
      for(unsigned i = 0; i < count; ++i)
         f();
      time = t.elapsed();
      if(time < result)
         result = time;
      t.restart();
   }
#ifdef _WIN32
   SetThreadPriority(GetCurrentThread(), old_priority);
#endif
   return result / count;
}

struct test_info
{
   test_info(const char* n, void (*p)());
   const char* name;
   void (*proc)();
};

inline bool operator < (const test_info& a, const test_info& b)
{
   return std::strcmp(a.name, b.name) < 0;
}

extern void consume_result(double);
extern void set_call_count(int i);
extern void add_new_test(test_info i);

inline test_info::test_info(const char* n, void (*p)())
{
   name = n;
   proc = p;
   add_new_test(*this);
}

#define BOOST_MATH_PERFORMANCE_TEST(name, string) \
   void BOOST_JOIN(name, __LINE__) ();\
   namespace{\
   test_info BOOST_JOIN(BOOST_JOIN(name, _init), __LINE__)(string, BOOST_JOIN(name, __LINE__));\
   }\
   void BOOST_JOIN(name, __LINE__) ()



#endif // BOOST_MATH_PERFORMANCE_MEASURE_HPP