呼出をトレースして実行時間を取る

Boost.ChronoでTrace - Faith and Brave - C++で遊ぼう
chronoがライブラリにまだ入っていないので導入はちょっと・・・
ということで作った。
車輪の再発明臭いけど気にしない。

elapsed_time.hpp

#pragma once

#include <algorithm>
#include <boost/current_function.hpp>
#include <boost/format.hpp>
#include <boost/function.hpp>
#include <boost/timer.hpp>
#include <pstade/napkin.hpp>

//definition
//ELAPSED_TIME_OUTPUT_TO_DEBUGGER
//ELAPSED_TIME_OUTPUT_TO_STDOUT	//as default

#if defined ELAPSED_TIME_OUTPUT_TO_DEBUGGER
#include <pstade/napkin/dout.hpp>
#else
#include <iostream>
#endif

namespace hwm
{
namespace elapsed_time_detail
{
	struct elapsed_time
	{
		typedef
			elapsed_time
		this_type;

		typedef 
			boost::function<
				void(this_type const&)
			>
		reporter_t;

		elapsed_time	(const char* file, const size_t line, const char* func, reporter_t r) 
			:	sum_	(0)
			,	min_	(0)
			,	max_	(0)
			,	count_	(0)
			,	file_	(file)
			,	line_	(line)
			,	func_	(func)
			,	r_		(r)
		{}

		~elapsed_time	() { try { r_(*this); } catch(...){} }

		void add(double elapse) {
			max_ = (std::max)(elapse, max_);
			min_ = (count_) ? (std::min)(elapse, min_) : elapse;
			sum_ += elapse;
			++count_;
		}

		const char*
				get_func	() const { return func_; }
		const char*
				get_file	() const { return file_; }
		size_t	get_line	() const { return line_; }
		double	get_min		() const { return min_; }
		double	get_max		() const { return max_; }
		double	get_total	() const { return sum_; }
		double	get_average	() const { return (count_) ? sum_ / count_ : 0; }
		size_t	get_count	() const { return count_; }
		void	set_reporter(reporter_t& r) { r_ = r; }

		void	clear		()
		{
			sum_ = min_ = max_ = count_ = 0;
		}

		double				sum_;
		double				min_;
		double				max_;
		size_t				count_;
		const char*			file_;
		const int			line_;
		const char*			func_;
		reporter_t			r_;
	};

	template<typename T>
	struct ScopedAdd
	{
		T&				t_;
		boost::timer	timer_;
		ScopedAdd		(T& t) : t_(t) {}
		~ScopedAdd		() { t_.add(timer_.elapsed()); }
	};

	struct default_reporter
	{
		template<typename T>
		void operator()(T const &t) const
		{
			pstade::napkin::ostream os;
#if defined ELAPSED_TIME_OUTPUT_TO_DEBUGGER
			os.reset(pstade::napkin::dout);
#else
			os.reset(std::cout);
#endif
			os <<
				boost::format(
					"%s(%d)\n"
					"\tfunc    : %s\n"
					"\taverage : %10.8f\n"
					"\tmin     : %10.8f\n"
					"\tmax     : %10.8f\n"
					"\ttotal   : %10.8f秒(%d回の呼び出し)\n")
					%	t.get_file()
					%	t.get_line()
					%	t.get_func()
					%	t.get_average()
					%	t.get_min()
					%	t.get_max()
					%	t.get_total()
					%	t.get_count();
		}
	};

}	//elapsed_time_detail
}	//hwm

#define HWM_ELAPSED_TIME()\
	static hwm::elapsed_time_detail::elapsed_time\
		BOOST_PP_CAT(hwm_elapsed_time_, __LINE__) (\
			__FILE__,\
			__LINE__,\
			BOOST_CURRENT_FUNCTION,\
			hwm::elapsed_time_detail::default_reporter()\
		);\
		hwm::elapsed_time_detail::ScopedAdd<\
			 hwm::elapsed_time_detail::elapsed_time	\
		>\
		BOOST_PP_CAT(hwm_elapsed_time_scoped_add, __LINE__)\
			(BOOST_PP_CAT(hwm_elapsed_time_, __LINE__));

test.cpp

#include <iostream>

//output result to debug window
//#define ELAPSED_TIME_OUTPUT_TO_DEBUGGER
#include "elapsed_time.hpp"

class A
{
public:
	A() {
		HWM_ELAPSED_TIME();
	}
};

void func()
{
	HWM_ELAPSED_TIME();
	for(int i = 0; i < 1000; ++i) {
		HWM_ELAPSED_TIME();
		A a;
		HWM_ELAPSED_TIME();
		A aa;
		{
			HWM_ELAPSED_TIME();
			A aaa;
		}
	}
}

int main()
{
	HWM_ELAPSED_TIME();
	for(int i = 0; i < 1000;++i) {
		func();
	}
}
C:\vc\test\elapsed_time_test>test
test.cpp(24)
        func    : void __cdecl func(void)
        average : 0.00000017秒
        min     : 0.00000000秒
        max     : 0.01600000秒
        total   : 0.17400000秒(1000000回の呼び出し)
test.cpp(21)
        func    : void __cdecl func(void)
        average : 0.00000041秒
        min     : 0.00000000秒
        max     : 0.01600000秒
        total   : 0.40700000秒(1000000回の呼び出し)
test.cpp(11)
        func    : __thiscall A::A(void)
        average : 0.00000005秒
        min     : 0.00000000秒
        max     : 0.01600000秒
        total   : 0.15500000秒(3000000回の呼び出し)
test.cpp(19)
        func    : void __cdecl func(void)
        average : 0.00000063秒
        min     : 0.00000000秒
        max     : 0.01600000秒
        total   : 0.62500000秒(1000000回の呼び出し)
test.cpp(17)
        func    : void __cdecl func(void)
        average : 0.00073400秒
        min     : 0.00000000秒
        max     : 0.01600000秒
        total   : 0.73400000秒(1000回の呼び出し)
test.cpp(32)
        func    : int __cdecl main(void)
        average : 0.73400000秒
        min     : 0.73400000秒
        max     : 0.73400000秒
        total   : 0.73400000秒(1回の呼び出し)

msvc9.0, gcc4.5.0, boost1.42.0, pstade1.04.3で確認。