On Tuesday 08 April 2014 07:42:46 Thiago Macieira wrote:
> Em ter 08 abr 2014, às 15:49:16, Volker Krause escreveu:
> > API-wise we are quite flexible (can't get any more dirty than what we do
> > now ;) ), I was mainly asking due to this being on a performance-relevant
> > path. The QInternal callback system is obviously more flexible (and thus
> > would be my preferred choice), but also slightly more expensive at
> > runtime. The signal spy approach would be slightly more light-weight, at
> > the cost of thread-safety. So, if from the performance point of view
> > there are no objections to the QInternal callback approach, I'll make
> > sure the Squish team is happy with that too, and propose a patch
> > accordingly.
> 
> Performance-wise, I'd prefer empty functions that get overridden at runtime.
> That's the smallest overhead for when they are not present.

According to a quick benchmark (attached), it is clearly more efficient to 
have:
  if (callback) callback();
where callback is a function pointer than always calling callback even if it 
is an empty function.

For this reason, I'd recommend an approach based on function pointer callbacks 
such as QInternal::registerCallback
(but that one is using a QGlobalStatic, so there is room for improvement)

-- 
Olivier 

Woboq - Qt services and support - http://woboq.com - http://code.woboq.org
#include <QtCore/QElapsedTimer>
#include <QtCore/QDebug>

extern "C" void noop();

void (*test1_ptr)() = noop;
void (*test2_ptr)() = 0;

static int test1() {
    test1_ptr();
    return 42;
}

static int test2() {
    if (test2_ptr)
        test2_ptr();
    return 42;
}

static int test3() {
    noop();
    return 42;
}


int main() {

    quint64 r;
    QElapsedTimer t;

    t.start();
    for(quint64 i = 0; i <  500 * 1000 * 1000; ++i)
        test3();
    r = t.elapsed();
    qDebug() << "test3: " << r;



    t.start();
    for(quint64 i = 0; i <  500 * 1000 * 1000; ++i)
        test1();
    r = t.elapsed();
    qDebug() << "test1: " << r;

    t.start();
    for(quint64 i = 0; i <  500 * 1000 * 1000; ++i)
        test2();
    r = t.elapsed();
    qDebug() << "test2: " << r;

    t.start();
    for(quint64 i = 0; i <  500 * 1000 * 1000; ++i)
        test3();
    r = t.elapsed();
    qDebug() << "test3: " << r;

    t.start();
    for(quint64 i = 0; i <  500 * 1000 * 1000; ++i)
        test3();
    r = t.elapsed();
    qDebug() << "test3: " << r;


    t.start();
    for(quint64 i = 0; i <  500 * 1000 * 1000; ++i)
        test2();
    r = t.elapsed();
    qDebug() << "test2: " << r;

    t.start();
    for(quint64 i = 0; i <  500 * 1000 * 1000; ++i)
        test1();
    r = t.elapsed();
    qDebug() << "test1: " << r;



}

extern "C"  __attribute__((visibility("default")))  void noop() {};
_______________________________________________
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development

Reply via email to