Russian Qt Forum

Qt => Общие вопросы => Тема начата: Авварон от Ноябрь 11, 2009, 16:40



Название: виртуальные слоты
Отправлено: Авварон от Ноябрь 11, 2009, 16:40
Собственно вопрос по виртуальным слотам. В доке написано что они жутко медленные. Почему? Ведь такая реализация делает слот open виртуальным (за исключением небольшого неудобства с тем что переопределять надо не слот, а лишнюю функцию):
Код:
#ifndef QMPQABSTRACTEDITOR_H
#define QMPQABSTRACTEDITOR_H

#include <QObject>
#include <QDebug>

class QMPQAbstractEditor : public QObject
{
    Q_OBJECT
public:
    QMPQAbstractEditor();
    virtual void vopen() = 0;

public slots:
    void open() {this->vopen();}
};

class test :public QMPQAbstractEditor
{
    void vopen() {qDebug() << "lol";}
};

#endif // QMPQABSTRACTEDITOR_H

    QMPQAbstractEditor * e = new test();
    connect(ui->action, SIGNAL(triggered()), e, SLOT(open())); //печатает lol


Название: Re: виртуальные слоты
Отправлено: Alex Custov от Ноябрь 11, 2009, 18:35
Собственно вопрос по виртуальным слотам. В доке написано что они жутко медленные. Почему?

Очевидно затраты на конечный вызов слота, плюс затраты на вызов виртуального метода.


Название: Re: виртуальные слоты
Отправлено: Igors от Ноябрь 11, 2009, 19:25
Если говорить о virtual в контексте ++ (без слотов/сигналов) - то упоминание о "замедлении" это просто атавизм конца 80-х (хорошо видно в ассемблере).

Со слотами/сигналами все может быть сложнее но никак не вижу почему слот может замедлять?  Может быть сигнал? Вообще где это написано, "ткните носиком"  :)


Название: Re: виртуальные слоты
Отправлено: Alex Custov от Ноябрь 11, 2009, 19:41
Со слотами/сигналами все может быть сложнее но никак не вижу почему слот может замедлять?  Может быть сигнал? Вообще где это написано, "ткните носиком"  :)

в общем случае замедляет сама система сигнал-слот, т.к. даже прямой вызов слота проходит определённые стадии выполнения разного кода, т.е. не так быстр как вызов обычного метода. А если к одному сигналу подключено несколько слотов, то соответственно задержка вызова слота будет ещё больше.


Название: Re: виртуальные слоты
Отправлено: fuCtor от Ноябрь 11, 2009, 20:08
Со слотами/сигналами все может быть сложнее но никак не вижу почему слот может замедлять?  Может быть сигнал? Вообще где это написано, "ткните носиком"  :)

в общем случае замедляет сама система сигнал-слот, т.к. даже прямой вызов слота проходит определённые стадии выполнения разного кода, т.е. не так быстр как вызов обычного метода. А если к одному сигналу подключено несколько слотов, то соответственно задержка вызова слота будет ещё больше.

А чем отличается вызов слота напрямую от вызова обычного метода? Почему-то всегда считал, что они равнозначным (если судить по генерируемому коду moc-ом). Модификатор slots нужен лишь для указания moc о формировании оберток для непрямого вызова через метаобъект, не более.


Название: Re: виртуальные слоты
Отправлено: Alex Custov от Ноябрь 11, 2009, 20:15
А чем отличается вызов слота напрямую от вызова обычного метода? Почему-то всегда считал, что они равнозначным (если судить по генерируемому коду moc-ом). Модификатор slots нужен лишь для указания moc о формировании оберток для непрямого вызова через метаобъект, не более.

Я ведь так и написал - когда ты вызываешь один метода, это одна строка кода, а когда емитишь сигнал - коды выполняется больше, поэтому это медленнее. А если используется queueded connection - ещё медленнее.


Название: Re: виртуальные слоты
Отправлено: Igors от Ноябрь 11, 2009, 20:41
в общем случае замедляет сама система сигнал-слот, т.к. даже прямой вызов слота проходит определённые стадии выполнения разного кода, т.е. не так быстр как вызов обычного метода. А если к одному сигналу подключено несколько слотов, то соответственно задержка вызова слота будет ещё больше.
"в общем случае", "определённые стадии", "разного кода". Мудрено :) Алексей, чего гадать на кофейной гуще если есть исходники? Вот, например, moc который сгенерировал учебный пример tabdialg

Код:
void *TabDialog::qt_metacast(const char *_clname)
{
    if (!_clname) return 0;
    if (!strcmp(_clname, qt_meta_stringdata_TabDialog))
        return static_cast<void*>(const_cast< TabDialog*>(this));
    return QDialog::qt_metacast(_clname);
}

int TabDialog::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QDialog::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: TabChanged((*reinterpret_cast< int(*)>(_a[1]))); break;
        default: ;
        }
        _id -= 1;
    }
    return _id;
}
Где затраты, на что? На strcmp? Да. есть такое дело, в любом случае это вызов ф-ции да еще может быть из dll. Но ведь ф-ция одна из самых быстрых. Быстро/медленно - относительно, К чему мерять? Если, например, к такому

Код:
QString s = "Alex";
s += "_1";

То о расходах на вызов слота неудобно и вспоминать :) А вот при кратности вызова миллион и больше - да, это выльется в конкретные секунды. Но есть ли у Вас такие тяжелые вычисления? Нет - ну так и живите счастливо :) 


Название: Re: виртуальные слоты
Отправлено: Alex Custov от Ноябрь 11, 2009, 20:58
То о расходах на вызов слота неудобно и вспоминать :) А вот при кратности вызова миллион и больше - да, это выльется в конкретные секунды. Но есть ли у Вас такие тяжелые вычисления? Нет - ну так и живите счастливо :) 

Ну когда программисты говорят, что что-то медленное, то это не значит что это медленное с точки зрения человека ;) Вызов виртуального метода медленное, вызов виртуального слота ещё медленнее, но с точки зрения машины, а мы должны всегда думать как писать быстрый код, даже с точки зрения машины. Потому что это мозаика медленных вызовов может в итоге сложится в медленное приложение уже для человека, а не для машины. Вон как AIR работает, например :D


Название: Re: виртуальные слоты
Отправлено: Igors от Ноябрь 11, 2009, 21:37
Ну когда программисты говорят, что что-то медленное, то это не значит что это медленное с точки зрения человека ;) Вызов виртуального метода медленное, вызов виртуального слота ещё медленнее, но с точки зрения машины, а мы должны всегда думать как писать быстрый код, даже с точки зрения машины. Потому что это мозаика медленных вызовов может в итоге сложится в медленное приложение уже для человека, а не для машины. Вон как AIR работает, например :D
Ну, вообще говоря, я не программист, а "инженер-системотехник" как написано в моем дипломе который я получил в 1982 году. Пришлось работать "электронщиком" на ЕС-1033, потом ЕС-1052. Ну а потом пошли "персоналки" - и я воспрял :) Сейчас когда молодые люди говорят о продвинутых технологиях (наверное AIR это тоже такая) - ну я просто теряюсь. Куда уж мне, старому пердуну, угнаться. А вот задачи на пределе скорости/памяти - мне в кайф, этим сейчас и занимаюсь. Ничего "крутого" здесь нет, просто специфика (которая мне лично нравится).


Название: Re: виртуальные слоты
Отправлено: Kagami от Ноябрь 13, 2009, 09:45
А где в документации написано что виртуальные слоты тормознее? В обзоре слотов (http://doc.crossplatform.ru/qt/4.5.0/signalsandslots.html#slots) сказано что все слоты примерно в 10 раз медленнее прямого вызова невиртуальной функции, но при этом
Цитировать
На i586-500 вы можете генерировать около 2,000,000 сигналов, связанных с одним слотом, в секунду, или около 1,200,000 сигналов, связанных с двумя слотами, в секунду.


Название: Re: виртуальные слоты
Отправлено: lit-uriy от Ноябрь 13, 2009, 11:11
Kagami, по моему там вообще только одно упоминание о виртуальных слотах:
Цитировать
Вы также можете определять виртуальные слоты, что мы находим очень полезным на практике.