switch_case对象

本文通过实验对比了二分查找与传统Switch语句在处理大量数据时的效率差异,结果显示二分查找虽然试探次数更多,但在实际运行中耗时相近甚至更优,暗示现代编译器可能对Switch采用O(n)遍历优化。
/********************************************************************
*  文件名:   CLK_LIB.h
*  文件描述: Switch_Case对象
*  创建人:   陈泽丹 ,2012年8月27日     
*  版本号:   1.0
*  修改记录:
********************************************************************/


#include <iostream>
#include <tchar.h>
#include <windows.h>


using namespace std;

//时间守卫 - 用于测试经历时间
class Time_Guard
{
public:
	Time_Guard(const char* _p_caption)
	{
		if( m_is_open)
		{
			size_t len = strlen(_p_caption);
			if( len < MAX_PATH ) 
			{
				sprintf(m_caption,"%s", _p_caption);
			}
			else
			{
				sprintf(m_caption, "%s", "Error: caption is over stack! ");
				cout<<"Error: "<<_p_caption<<"is over stack!"<<endl;
			}
			m_time = GetTickCount();
		}
	}
	~Time_Guard()
	{
		if( m_is_open)
		{
			ULONG tm = GetTickCount() - m_time;
			cout<<m_caption<<": "<<tm<<" (ms)"<<endl;
		}
	}
	static void set_state(bool _is_open){ m_is_open = _is_open; }
private:
	static bool m_is_open;
	char m_caption[256];
	ULONG m_time;
};
bool Time_Guard::m_is_open = true;


extern int count1 = 0;
extern int coutn2 = 0;
//Switch_Case对象
template< template< int v > class _PAR_TYPE, int _start, int _end>  
class CLK_Switch
{
public:
	template <class _PtrObj>
	static bool switch_case(const _PtrObj& _p, const int _msg_type_ID, void* buf)
	{
		if( _msg_type_ID < _start || _msg_type_ID > _end || _start > _end) 
			return false;  
		const int POS = (_start + _end)/2;  
		if( POS == _msg_type_ID)
		{
			_PAR_TYPE< POS >* p_msg = ( _PAR_TYPE< POS >* ) buf;
			_p->dispatch( p_msg );
			return true;
		}
		else if( _msg_type_ID  < POS  ) 
		{
			count1++;
			return CLK_Switch<_PAR_TYPE, _start, POS>::switch_case(_p, _msg_type_ID, buf);
		}
		else
		{
			count1++;
			return CLK_Switch<_PAR_TYPE, POS+1, _end>::switch_case(_p, _msg_type_ID, buf);
		}
	}
};
template< class _Local_Type>  
class CLK_Base_Case
{
public:
	CLK_Base_Case(_Local_Type* _p_local):m_p_local(_p_local){}
	virtual ~CLK_Base_Case(){ m_p_local = NULL; }
	virtual void operator()(const int _msg_type_ID, void* buf) = 0;
protected:
	_Local_Type* m_p_local;
};


 

/********************************************************************
*  文件名:   Main.h
*  文件描述: Switch_Case对象
*  创建人:   陈泽丹 ,2012年8月27日     
*  版本号:   1.0
*  修改记录:
********************************************************************/

#include <iostream>
#include <vector>
#include "CLK_LIB.h"

using namespace std;


template< int v >  
class CLK_MSG  
{  
public:  
	enum { MSG_TYPE_ID = v }; 
}; 


class CLK_SERVER_MSG
{  
public:
	enum
	{
		MSG_START = 0,
		MSG_END = 8,
	};
	class Action_Msg_Case: public CLK_Base_Case<CLK_SERVER_MSG>
	{
	public:
		Action_Msg_Case(CLK_SERVER_MSG* _p):CLK_Base_Case<CLK_SERVER_MSG>(_p){}
		virtual void operator()(const int _msg_type_ID, void* buf)
		{
			CLK_Switch<CLK_MSG, MSG_START, MSG_END>::switch_case(this, _msg_type_ID, buf);
		}
		template<class _T>
		bool dispatch(_T* _msg)
		{
			//cout<<"通用操作!"<<endl;
			count1++;
			return true;
		}
		bool dispatch(CLK_MSG<1>* _msg)
		{
			//cout<<"my_dispatch!"<<endl;
			count1++;
			Sleep(2);
			return true;
		}
		bool dispatch(CLK_MSG<2>* _msg)
		{
			//cout<<"my_dispatch!"<<endl;
			count1++;
			Sleep(2);
			return true;
		}
		bool dispatch(CLK_MSG<3>* _msg)
		{
			//cout<<"my_dispatch!"<<endl;
			count1++;
			Sleep(2);
			return true;
		}
		bool dispatch(CLK_MSG<4>* _msg)
		{
			//cout<<"my_dispatch!"<<endl;
			count1++;
			Sleep(2);
			return true;
		}
		bool dispatch(CLK_MSG<5>* _msg)
		{
			//cout<<"my_dispatch!"<<endl;
			count1++;
			Sleep(2);
			return true;
		}
		bool dispatch(CLK_MSG<6>* _msg)
		{
			//cout<<"my_dispatch!"<<endl;
			count1++;
			Sleep(2);
			return true;
		}
		bool dispatch(CLK_MSG<7>* _msg)
		{
			//cout<<"my_dispatch!"<<endl;
			count1++;
			Sleep(2);
			return true;
		}
		bool dispatch(CLK_MSG<8>* _msg)
		{
			//cout<<"my_dispatch!"<<endl;
			count1++;
			Sleep(2);
			return true;
		}
	};

	CLK_SERVER_MSG():action_msg_case(this){}
	Action_Msg_Case action_msg_case;
	virtual void on_action(const int _msg_type_ID, void* buf)
	{
		action_msg_case(_msg_type_ID, buf);
	}

	virtual void on_action1(const int _msg_type_ID, void* buf)
	{
		switch(_msg_type_ID)
		{
		case 1: coutn2++; Sleep(2); break;
		case 2: coutn2++; Sleep(2); break;
		case 3: coutn2++; Sleep(2); break;
		case 4: coutn2++; Sleep(2); break;
		case 5: coutn2++; Sleep(2); break;
		case 6: coutn2++; Sleep(2); break;
		case 7: coutn2++; Sleep(2); break;
		case 8: coutn2++; Sleep(2); break;
		default: coutn2++;  break;
		}
	}


};

void Server()
{
	Time_Guard tm_guard("Server msg");
	CLK_SERVER_MSG msg;
	for(int i=0; i<2000; i++)
		msg.on_action(i%9, "123");
	cout<<count1<<endl;
}

void Server1()
{
	Time_Guard tm_guard("Server case");
	CLK_SERVER_MSG msg;
	for(int i=0; i<2000; i++)
		msg.on_action1(i%9, "123");
	cout<<coutn2<<endl;
}

void main()
{
	Server();
	Server1();
	system("pause");
}

 

5557
Server msg: 5203 (ms)
2000
Server case: 5219 (ms)
请按任意键继续. . .

 

 

2000次调用case语句, 二分查找要试探5557次, 用系统的switch_case只要试探2000, 但二分查找的耗时和switch_case相差不下,甚至更快。 可见系统底层对switch_case很可能就是用o(n)遍历的算法的。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值