mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-31 04:50:34 -04:00 
			
		
		
		
	
		
			
	
	
		
			116 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			116 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | //  Copyright John Maddock 2015.
 | ||
|  | //  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 PERFORMANCE_HPP
 | ||
|  | #define PERFORMANCE_HPP
 | ||
|  | 
 | ||
|  | #include <boost/math/special_functions/relative_difference.hpp>
 | ||
|  | #include <boost/array.hpp>
 | ||
|  | #include <boost/chrono.hpp>
 | ||
|  | #include <boost/regex.hpp>
 | ||
|  | 
 | ||
|  | template <class Array> | ||
|  | void add_data(const Array& a) | ||
|  | { | ||
|  |    //
 | ||
|  |    // This function is called multiple times to merge multiple data sets into one big table:
 | ||
|  |    //
 | ||
|  |    for(typename Array::const_iterator i = a.begin(); i != a.end(); ++i) | ||
|  |    { | ||
|  |       data.push_back(std::vector<double>()); | ||
|  |       for(typename Array::value_type::const_iterator j = i->begin(); j != i->end(); ++j) | ||
|  |       { | ||
|  |          data.back().push_back(*j); | ||
|  |       } | ||
|  |    } | ||
|  | } | ||
|  | 
 | ||
|  | template <class Func, class Result> | ||
|  | void screen_data(Func f, Result r) | ||
|  | { | ||
|  |    //
 | ||
|  |    // If any of the implementations being tested produces garbage for one of our
 | ||
|  |    // test cases (or else if we test a domain they don't support), then we remove that
 | ||
|  |    // row from the table.  This allows us to only test a common supported sub-set for performance:
 | ||
|  |    //
 | ||
|  |    for(std::vector<std::vector<double> >::size_type row = 0; row < data.size(); ++row) | ||
|  |    { | ||
|  |       try | ||
|  |       { | ||
|  |          double computed = f(data[row]); | ||
|  |          double expected = r(data[row]); | ||
|  |          double err = boost::math::relative_difference(computed, expected); | ||
|  |          if(err > 1e-7) | ||
|  |          { | ||
|  |             std::cout << "Erasing row: "; | ||
|  |             for(unsigned i = 0; i < data[row].size(); ++i) | ||
|  |             { | ||
|  |                std::cout << data[row][i] << " "; | ||
|  |             } | ||
|  |             std::cout << "Error was " << err << std::endl; | ||
|  |             data.erase(data.begin() + row); | ||
|  |             --row; | ||
|  |          } | ||
|  |       } | ||
|  |       catch(const std::exception& e) | ||
|  |       { | ||
|  |          std::cout << "Erasing row: "; | ||
|  |          for(unsigned i = 0; i < data[row].size(); ++i) | ||
|  |          { | ||
|  |             std::cout << data[row][i] << " "; | ||
|  |          } | ||
|  |          std::cout << "due to thrown exception: " << e.what() << std::endl; | ||
|  |          data.erase(data.begin() + row); | ||
|  |          --row; | ||
|  |       } | ||
|  |    } | ||
|  | } | ||
|  | 
 | ||
|  | template <class Clock> | ||
|  | struct stopwatch | ||
|  | { | ||
|  |    typedef typename Clock::duration duration; | ||
|  |    stopwatch() | ||
|  |    { | ||
|  |       m_start = Clock::now(); | ||
|  |    } | ||
|  |    duration elapsed() | ||
|  |    { | ||
|  |       return Clock::now() - m_start; | ||
|  |    } | ||
|  |    void reset() | ||
|  |    { | ||
|  |       m_start = Clock::now(); | ||
|  |    } | ||
|  | 
 | ||
|  | private: | ||
|  |    typename Clock::time_point m_start; | ||
|  | }; | ||
|  | 
 | ||
|  | double sum = 0; | ||
|  | 
 | ||
|  | template <class Func> | ||
|  | double exec_timed_test(Func f) | ||
|  | { | ||
|  |    double t = 0; | ||
|  |    unsigned repeats = 1; | ||
|  |    do{ | ||
|  |       stopwatch<boost::chrono::high_resolution_clock> w; | ||
|  | 
 | ||
|  |       for(unsigned count = 0; count < repeats; ++count) | ||
|  |       { | ||
|  |          for(std::vector<std::vector<double> >::const_iterator i = data.begin(); i != data.end(); ++i) | ||
|  |             sum += f(*i); | ||
|  |       } | ||
|  | 
 | ||
|  |       t = boost::chrono::duration_cast<boost::chrono::duration<double>>(w.elapsed()).count(); | ||
|  |       if(t < 0.5) | ||
|  |          repeats *= 2; | ||
|  |    } while(t < 0.5); | ||
|  |    return t / (repeats * data.size()); | ||
|  | } | ||
|  | 
 | ||
|  | #endif // PERFORMANCE_HPP
 |