深圳夜归人

繁华的都市,有谁记得我们的脚步?

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
乱七八糟,有空再整理。

1、暂命名为Functor,因为没考虑返回值的情况,这在多分派委托处理中,算是个麻烦事,以后类名可能改为Delegate。
2、根据i_like_cpp翻译的技术文章《成员函数指针与高性能的C++委托》提供的思路做成的,不过原文所提到的FastDelegate实现太复杂,所以自己做了一个,可能不完善,不过初步测试基本功能达到了,而且实现要简单一些。
3、原本vector遍历用的是迭代器,不过测试发现速度比用下标访问慢10倍以上,改成下标访问,测试表明速度已经和直接调用差不多。实际测试结果非常相近,用GetTickCount获取的结果,有时是直接调用要快一些,有时是使用Functor要快一些,当然Functor不可能比直接调用还快。
4、实现没有写完,先写了3个版本做测试用,成型以后会实现更多版本(支持更多参数)。下午一时心血来潮写成的,离成型还很远,不过从效率测试来看值得做。



#include <vector> 
#include 
<functional> 
#include 
<iostream> 
#include 
<string> 
#include 
<windows.h> 
using namespace std; 

struct Test 

    
int n; 
    Test () : n(
3{} 
    
void test0() 
    

        
//cout << "Test::test0: " << n << endl; 
    }
 

    
void test1(int i) 
    

        
//cout << "Test::test1: " << i << endl; 
    }
 

    
void test2(const string& a, int b) 
    

        
//cout << "Test::test2: " << a << "|" << b << endl; 
    }
 
}


void test0 () 

    
//cout << "test0" << endl; 
}
 

void test1 (int i) 

    
//cout << "test1: " << i << endl; 
}
 

void test2(const string& a, int b) 

    
//cout << "test2: " << a << "|" << b << endl; 
}
 

struct NullType {}

template 
<typename R, typename A=NullType, typename B=NullType, typename C=NullType, 
typename D
=NullType, typename E=NullType, typename F=NullType, typename G=NullType, 
typename H
=NullType, typename I=NullType, typename J=NullType, typename K=NullType, 
typename L
=NullType, typename M=NullType, typename N=NullType, typename O=NullType> 
class Functor 

}


template 
<typename R> 
struct Functor <R> 

    vector 
<pair<void*void*> > _handlers; 
    typedef R(
*F)(); 

    
void add (F f) 
    

        _handlers.push_back (make_pair ((
void*)0, (void*)f)); 
    }
 

    template 
<typename T> 
    
void add (const pair<T*, typename R(T::*)()>& f) 
    

        typedef R(T::
*P)(); 
        
struct Pointer {P p;}
        Pointer ptr 
= {f.second}
        _handlers.push_back (make_pair ((
void*)f.first, *(void**)&ptr)); 
    }
 

    
void call () 
    

        
for (size_t i=0; i<_handlers.size (); i++
        

            
void* p = _handlers[i].first; 
            
if (p) // member function 
            
                
void* mem_fun = _handlers[i].second; 
                __asm

                    mov ecx, p 
                    call mem_fun 
                }
 
            }
 
            
else 
            

                (
*(F)_handlers[i].second)(); 
            }
 
        }
 
    }
 
}


template 
<typename R, typename A> 
struct Functor <R, A> 

    vector 
<pair<void*void*> > _handlers; 
    typedef R(
*F)(A); 

    
void add (F f) 
    

        _handlers.push_back (make_pair ((
void*)0, (void*)f)); 
    }
 

    template 
<typename T> 
    
void add (const pair<T*, typename R(T::*)(A)>& f) 
    

        typedef R(T::
*P)(A); 
        
struct Pointer {P p;}
        Pointer ptr 
= {f.second}
        _handlers.push_back (make_pair ((
void*)f.first, *(void**)&ptr)); 
    }
 

    
void call (A a) 
    

        
for (size_t i=0; i<_handlers.size (); i++
        

            
void* p = _handlers[i].first; 
            
if (p) // member function 
            
                
void* mem_fun = _handlers[i].second; 
                __asm

                    push a 
                    mov ecx, p 
                    call mem_fun 
                }
 
            }
 
            
else 
            

                (
*(F)_handlers[i].second)(a); 
            }
 
        }
 
    }
 
}


template 
<typename R, typename A, typename B> 
struct Functor <R, A, B> 

    vector 
<pair<void*void*> > _handlers; 
    typedef R(
*F)(A, B); 

    
void add (F f) 
    

        _handlers.push_back (make_pair ((
void*)0, (void*)f)); 
    }
 

    template 
<typename T> 
    
void add (const pair<T*, typename R(T::*)(A, B)>& f) 
    

        typedef R(T::
*P)(A, B); 
        
struct Pointer {P p;}
        Pointer ptr 
= {f.second}
        _handlers.push_back (make_pair ((
void*)f.first, *(void**)&ptr)); 
    }
 

    
void call (A a, B b) 
    

        
for (size_t i=0; i<_handlers.size (); i++
        

            
void* p = _handlers[i].first; 
            
if (p) // member function 
            
                
void* mem_fun = _handlers[i].second; 
                __asm

                    push b 
                    push a 
                    mov ecx, p 
                    call mem_fun 
                }
 
            }
 
            
else 
            

                (
*(F)_handlers[i].second)(a, b); 
            }
 
        }
 
    }
 
}



int main(int argc, char* argv[]) 

    Test t; 
    DWORD cur 
= GetTickCount (); 
    
for (int i=0; i<10000000; i++
    

        t.test0(); 
    }
 
    cout 
<< (GetTickCount() - cur) << endl; 

    Functor 
<void> f; 
    f.add (make_pair(
&t, &Test::test0)); 
    f.add (test0); 
    cur 
= GetTickCount (); 
    
for (int i=0; i<1000000; i++
    

        f.call(); 
    }
 
    cout 
<< (GetTickCount() - cur) << endl; 

    f.call ();

    Functor
<voidint> f1; 
    f1.add (test1); 
    f1.add (make_pair (
&t, &Test::test1)); 
    f1.add (test1); 
    f1.add (test1); 
    f1.call (
93); 

    Functor
<voidconst string&int> f2; 
    f2.add (test2); 
    f2.add (make_pair (
&t, &Test::test2)); 
    f2.add (test2); 
    f2.add (test2); 
    f2.call (
string("hello"), 5); 
    
return 0
}
 
posted on 2005-07-22 18:19  cpunion  阅读(1268)  评论(6编辑  收藏  举报