简体   繁体   English

C ++:非模板委托类上的性能提高

[英]c++: Performance increase on non-template delegate class

This is a simple delegate class that only works for methods of the format void ClassType::MethodType( InputType& ), but can easily be expanded to more generic functions, not shown simply because it would be too large. 这是一个简单的委托类,仅适用于void ClassType :: MethodType(InputType&)格式的方法,但可以轻松地扩展为更通用的函数,因为它太大了,所以无法显示。

class Delegate
{
public:
    Delegate( void ) : Object( NULL ), Argument( NULL ) { }
    virtual ~Delegate( void ) { }

    template <class ClassType, class InputType, void (ClassType::*MethodType)( InputType )>
    void Create( ClassType* SetObject, void* SetArgument = NULL )
    {
        Object = SetObject;
        Argument = SetArgument;
        StaticCall = &CallMethod<ClassType, InputType, MethodType>;
    }

    template <class InputType>
    inline void operator()( InputType InputValue ) const
    {
        (*StaticCall)( Object, static_cast<void*>(InputValue) );
    }

    inline void operator()( void ) const
    {
        (*StaticCall)( Object, Argument );
    }

protected:
    typedef void (*FunctionCallType)( void*, void* );

    void* Object;
    void* Argument;
    FunctionCallType StaticCall;

private:
    template <class ClassType, class InputType, void (ClassType::*MethodType)( InputType )>
    static inline void CallMethod( void* SetObject, void* PassArgument )
    {
        (static_cast<ClassType*>( SetObject )->*MethodType)( static_cast<InputType>(PassArgument) );
    }
};

It's flexible and can be used to pool callback classes, but one problem I have with it is that so far it's on par with (or even slower when used in large vectors like I plan to) than a virtual call if it's used as a base class. 它很灵活,可以用于缓冲回调类,但是我遇到的一个问题是,到目前为止,它与虚拟调用(如果用作基础,甚至可以与虚拟调用相比)相提并论(甚至更慢)。类。 I'm looking for any suggestions on how to increase performance since I'm out of ideas, even if it affects functionality. 我一直在寻找关于如何提高性能的任何建议,因为我没有想法,即使它影响功能。

The simplest performance measuring code I used (with -O3) was: 我使用的最简单的性能评估代码(带有-O3)是:

class VirtualBase
{
public: 
    virtual void TestCall( int* Data ) {}
};

class VirtualTest : public VirtualBase
{
public:
    VirtualTest() : Value(0) {}

    void TestCall( int* Data )
    {
        Value += *Data;
    }
private:
    int Value;
};


class DelTest : public Delegate
{
public:
    DelTest() : Value(0)
    {
        Create<DelTest, int*, &DelTest::TestCall>( this );
    }

    void TestCall( int* Data )
    {
        Value += *Data;
    }
private:
    int Value;
};

int main( int argc, char **argv )
{
    clock_t start;
    int Value = 1;

    VirtualBase* NewBase = new VirtualTest;

    start = clock();
    for( size_t Index = 0; Index < 1000000000; ++Index )
    {
        NewBase->TestCall( &Value );
    }
    delete NewBase;
    std::cout << (( std::clock() - start ) / (double)CLOCKS_PER_SEC) << std::endl;


    Delegate* NewDBase = new DelTest;
    start = clock();
    for( size_t Index = 0; Index < 1000000000; ++Index )
    {
        NewDBase->operator()( &Value );
    }
    delete NewDBase;
    std::cout << (( std::clock() - start ) / (double)CLOCKS_PER_SEC) << std::endl;

    return 0;
}

I should mention that I'd like the class to stay non-template, as it makes classes using callbacks to anything easy to iterate through in a single vector. 我应该指出,我希望类保持非模板状态,因为它使使用回调的类在单个向量中易于迭代。

You might want to look at this Lightweight Generic C++ Callbacks article on CodeProject 您可能想看看CodeProject上的这篇轻量级通用C ++回调文章

Some of the code from the linked article, showing the use of a function template to do the forwarding: 链接文章中的一些代码,展示了如何使用功能模板进行转发:

template<typename R, typename P1, typename P2>
class Callback
{
public:
    typedef R (*FuncType)(void*, P1, P2);
    Callback() : func(0), obj(0) {}
    Callback(FuncType f, void* o) : func(f), obj(o) {}
    R operator()(P1 a1, P2 a2)
    {
        return (*func)(obj, a1, a2);
    }

private:
    FuncType func;
    void* obj;
};

template<typename R, class T, typename P1, typename P2, R (T::*Func)(P1, P2)>
R Wrapper(void* o, P1 a1, P2 a2)
{
    return (static_cast<T*>(o)->*Func)(a1, a2);
}

class Foo
{
public:
    float Average(int n1, int n2)
    {
        return (n1 + n2) / 2.0f;
    }
};

float Calculate(int n1, int n2, Callback<float, int, int> callback)
{
    return callback(n1, n2);
}

int main()
{
    Foo f;
    Callback<float, int, int> cb         
        (&Wrapper<float, Foo, int, int, &Foo::Average>, &f);
    float result = Calculate(50, 100, cb);
    // result == 75.0f
    return 0;
}

There is also a great write up on stackoverflow here which will give you better insight. 这里也有大量关于stackoverflow的文章它们将为您提供更好的见解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++非模板类的朋友成为模板类的成员 - c++ non-template class friends to a member of template class 非模板类中任何类型的C ++成员变量 - C++ member variable of any type in non-template class 是否有c ++的非模板元语言? - Is there a non-template metalanguage for c++? 模板类源自C ++中非模板基类的事件系统 - Event System with Template class deriving from Non-Template base class in c++ C ++:无法将参数1从子非模板类转换为父模板类 - C++: Cannot convert argument 1 from Child non-template class to Parent template class C ++ HowTo:从抽象的专用模板继承的非模板类 - C++ HowTo: Non-template class inheriting from an abstract specialized template 当我将带有非模板类的模板类放在同一cpp文件中时出现链接错误-C ++ - Link error when I put template class with non-template classes in same cpp file - C++ C ++标准是否允许非模板类的模板构造函数? - Does the C++ standard allow a template constructor for a non-template class? 在c ++中的非模板类中使用成员模板函数是否合适? - Is it good to have a member template function inside a non-template class in c++? C ++符号范围搜索顺序与模板和非模板类不同? - C++ symbol scope search order different for template and non-template class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM