Policyと実行時間
これまで
Policyをメンバ関数ポインタで - ...ing logging 3.0
Policyをboost::function+boost:bindで - ...ing logging 3.0
Policyのままで - ...ing logging 3.0
今回
Policyを使ったコードに比べて,boost::function + boost::bind がどれほど遅いのかを調べてみた.
VS2008のmsvcでReleaseビルド,最大限の最適化あり.
そしたら,Policyを使ったコードは最適化がうまく働いて実際には何も処理されなかったのか,実行時間がゼロになってしまった・・・.
なんてこったい.
一応,実験したコードを続きに張っておく.
追記
バカでかい数値をintで使うとか色々間違えていたので直した.
それと,何もない処理に展開されてしまうことがないように,mouse_event_loggerクラスのメソッドを副作用のあるものに変更した.
それでもやはりPolicyを使ったコードはゼロ秒(正確には1秒未満か?)で終わってしまった.
#include "stdafx.h" #include <ctime> #include <iostream> using namespace std; #include <boost/function.hpp> #include <boost/bind.hpp> using namespace boost; // 本来はどこかで定義されているものたち typedef int HWND; void MouseCapture(HWND){} void ReleaseCapture(){} HWND GetHWnd(){return 0;} class mouse_event_logger { long count_; public: mouse_event_logger() : count_(0) {} void on_left_button_down(){++count_;} void on_left_button_up(){++count_;} void on_right_button_down(){++count_;} void on_right_button_up(){++count_;} //... long count(){return count_;} }; #if 0 void f(function<void()> mouse_capture, function<void()> logger_method, bool enabled) { mouse_capture(); if (enabled) logger_method(); }; class context { bool enabled; mouse_event_logger logger; public: context() : enabled(false) {} void set_enabled(bool b) {enabled = b;} void on_left_button_down(HWND hwnd) { f(bind(::MouseCapture, hwnd), bind(&mouse_event_logger::on_left_button_down, &logger), enabled); } void on_left_button_up() { f(::ReleaseCapture, bind(&mouse_event_logger::on_left_button_up, &logger), enabled); } void on_right_button_down(HWND hwnd) { f(bind(::MouseCapture, hwnd), bind(&mouse_event_logger::on_right_button_down, &logger), enabled); } void on_right_button_up() { f(::ReleaseCapture, bind(&mouse_event_logger::on_right_button_up, &logger), enabled); } }; #else template <typename MouseEventPolicy> struct mouse_button_event_holder { void operator()(HWND hwnd, mouse_event_logger* logger, bool enabled) { MouseEventPolicy::mouse_capture(hwnd); if (enabled) MouseEventPolicy::logger_method(logger); }; }; struct on_left_button_down_policy { static void mouse_capture(HWND hwnd) { ::MouseCapture(hwnd); } static void logger_method(mouse_event_logger* logger) { logger->on_left_button_down(); } }; struct on_left_button_up_policy { static void mouse_capture(HWND hwnd) { ::ReleaseCapture(); } static void logger_method(mouse_event_logger* logger) { logger->on_left_button_up(); } }; struct on_right_button_down_policy { static void mouse_capture(HWND hwnd) { ::MouseCapture(hwnd); } static void logger_method(mouse_event_logger* logger) { logger->on_right_button_down(); } }; struct on_right_button_up_policy { static void mouse_capture(HWND ) { ::ReleaseCapture(); } static void logger_method(mouse_event_logger* logger) { logger->on_right_button_up(); } }; class context { bool enabled; mouse_event_logger logger; public: context() : enabled(false) {} ~context() { cout << logger.count() << endl; } void set_enabled(bool b) {enabled = b;} void on_left_button_down(HWND hwnd) { mouse_button_event_holder<on_left_button_down_policy>()(hwnd, &logger, enabled); } void on_left_button_up() { mouse_button_event_holder<on_left_button_up_policy>()(0, &logger, enabled); } void on_right_button_down(HWND hwnd) { mouse_button_event_holder<on_right_button_down_policy>()(hwnd, &logger, enabled); } void on_right_button_up() { mouse_button_event_holder<on_right_button_up_policy>()(0, &logger, enabled); } }; #endif int main() { time_t t1, t2; time(&t1); context c; c.set_enabled(true); for (long i=0; i<20000000; ++i) { c.on_left_button_down(GetHWnd()); c.on_left_button_up(); c.on_right_button_down(GetHWnd()); c.on_right_button_up(); } time(&t2); cout << t2-t1 << endl; return 0; }