Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: evilguard от Февраль 13, 2007, 01:34 Программа выполняет расчет, представляющий собой цикл из примерно 30000 итераций. Во время каждой итерации в QProgressBar посылается сигнал для отображения хода расчета. Так вот - от этого программа замедлилась с 10 до 15 секунд, таким образом за 1 секунду выполняется 6000 связываний сингал-слот, хотя в документации написано что "On an i586-500, you can emit around 2,000,000 signals per second connected to one receiver, or around 1,200,000 per second connected to two receivers." А ведь процессор у меня далеко не 586 а Pentium 4 3.7 GHz(двухъядерный, кеша 4МБ).
То есть в доках либо явное вранье, либо я что-то не понял. Еще возможно что замедляет работу функция QProgressBar::setValue(). Кто сталкивался с этим? добавлено спустя 52 минуты: В принципе необязательно конечно посылать сигнал после каждой итерации. Достаточно делать проверку условия и посылать сигнал, тогда когда увеличиваются сами проценты, тогда количество сигналов снизится с 33000 до 100. Так и правильнее будет. Но все-таки почему так медленно работает? В доках все в ажуре просто) Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: Racheengel от Февраль 13, 2007, 11:19 33000 до 100 - естессно, правильней :)
А медленно... ну... потому, что так Тролли сделали... Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: Tonal от Февраль 13, 2007, 11:23 Выброси всю работу из слота.
Бросай в пределах одного потока. Тады скорость будет соответствовать. P.S. Нафига обновлять прогресс на каждой итерации? Глазом всё равно не заметно - только систему грузишь зазря. ;-\ Обновляй на каждой 100ой - и горя не будешь знать. ;-) Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: evilguard от Февраль 13, 2007, 17:01 Tonal, Racheengel
Ессесно я сделал так. Заморачиваюсь по поводу скорости работы сигнал- слот я по другой причине: пишу программу трехмерного моделирования, основные классы которой: GLWidget MainWindow MObject. Программа отображает объекты MObject с помощью GLWidget. Контейнер объектов MObject объявлен в теле MainWindow, по понятным причинам - оттуда же работают диалоги которые влияют на отолбражаемые объекты. Каждый объект рисуется функцией MObject::Draw(). Сцена может изменятся динамически, поэтому при каждом изменении положения камеры(меняется мышью) желательно перерисовывать сцену. Для этого GLWidget должен посылать постоянно сигнал о перерисовке в MainWindow. Боюсь это сильно уменьшит скорость работы.. Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: SLiDER от Февраль 13, 2007, 17:11 Где-то читал небольшую статейку, название что-то типа "Почему в Qt для сигнал-слотов не используются шаблоны". Так вот в ней приводился сравнительный анализ ресурсоемкости шаблонного и тролевого механизмов и было заявлено, что в случае с Qt один вызов сигнала эквивалентен 10 вызовам обычных функций. Но это было для трехи, в четверки механиз был не слабо переделан и я думаю что вряд ли в сторону ускорения. Так что если приложение критично к скорости, то местами, может оказаться, лучше вообще отказаться от сигнал слотов. И изобрести какой-нибудь велосипед попроще, но побыстрее. :wink:
Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: Dendy от Февраль 15, 2007, 13:21 УвереньІ, что тормоза именно из-за вьІзова слота, а не из-за тела слота? Вообще вьІзов слота очень бьІстрьІй, Тролли не врут. Сравнительно медленно происходит именно связьІвать сигнала со слотом в методе QObject::connect().
Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: Alex Custov от Февраль 15, 2007, 14:38 не используйте QProgressBar в time-cost приложениях ! Он ОЧЕНЬ медленный. Лучше напишите свой на онове QWidget+QPainter. Он будет работать в ~10 раз быстрее. ;)
Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: evilguard от Февраль 15, 2007, 20:41 Dendy, Alex_X
Нет конечно, connect вызывался перед расчетом. Скорее всего дело в теле слота, то есть в самом QProgressBar. Вот так вот. Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: Mr. Пронька от Февраль 15, 2007, 22:23 Я думаю, такие обещания про миллионы срабатываний справедливы именно для самих срабатываний, без особых действий в обработчиках.
Достаточно сделать похожий проект в любой другой среде, хоть в том же Делфи. Засеки время выполнения чего-нибудь с отображением прогресса и без него. Сразу заметишь разницу. У меня в консольном приложении отображение прогресса выполнения замедляло цикл где-то в 50 раз. Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: Dendy от Февраль 16, 2007, 12:05 Попробуйте так:
Код: void MyObject::progress( float current ) Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: Alex Custov от Февраль 16, 2007, 14:49 это дублирование кода из QProgressBar. Так тоже есть проверки на текущее значение != новое значение. Дело не в значениях, а в том, что отрисовка текущего прогресса с помощью QStyle работает крайне медленно.
Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: Dimchansky от Февраль 18, 2007, 22:49 Я сделал замеры по числу отсылаемых сигналов.
Код: #include <iostream> На AMD Athlon 64 3000+ результаты: Код: Emited signals count: 10000000 Если сделать два получателя: Код: int main() То результаты такие: Код: Emited signals count: 10000000 Т.е. при увеличении числа получателей в два раза, время увеличилось в 1,328 раза. :) добавлено спустя 7 минут: Кстати, если кто-то напищет PerformanceTimer для Linux, можно будет сравнить результаты. :) Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: nova от Февраль 20, 2007, 10:44 Вот наваял тестик :)
Должен собиратся везде :) object1.h Код:
object1.cpp Код:
object2.h Код:
object2.cpp Код:
testobhect.h Код:
testobject.cpp Код:
main.cpp Код:
test.pro Код:
мои резултаты следующие: Цитировать cpu: Intel(R) Core(TM)2 Duo CPU 6400@ 2.13GHz Linux bear.alba.ua 2.6.19-1.2895.fc6 #1 SMP Wed Jan 10 18:50:56 EST 2007 x86_64 x86_64 x86_64 GNU/Linux $ ./test objectCall count: 100000000 objectCall total time: 0.339 Call per second: 294985250 objectCall2 count: 100000000 objectCall2 total time: 0.521 Call2 per second: 191938579 Emited signals count: 100000000 Total time: 42.859 Signals per second: 2333232 On two slot connected Emited signals count: 100000000 Total time: 60.505 Signals per second: 1652755 TestObject slot connected Emited signals count: 100000000 Total time: 40.296 Signals per second: 2481635 При работе теста грузится одно ядро. Вывод: вызов signal->slot в 100 раз медленнее чем просто вызв метода !!! Вот так вот :( Я конечно понимаю что за удобство надо платить :roll: Может имеет смысл начать пинать ( желательно сильно ) тролей на предмет оптимизации ентого места в КуТе ? Или всем скопом пооптимизировать 8) P.S. Попробуйте у себя позапускать тестик на разных машинках, интересно получить сравнительный результат. добавлено спустя 7 часов 42 минуты: На работе: Цитировать cpu: AMD Athlon(tm) @ 1252.851MHz Linux bw.alba.ua 2.6.19-1.2911.fc6 #1 SMP Sat Feb 10 15:03:33 EST 2007 i686 athlon i386 GNU/Linux $ ./test objectCall count: 100000000 objectCall total time: 0.805 Call per second: 124223602 objectCall2 count: 100000000 objectCall2 total time: 1.212 Call2 per second: 82508250 Emited signals count: 100000000 Total time: 127.591 Signals per second: 783754 On two slot connected Emited signals count: 100000000 Total time: 158.853 Signals per second: 629512 TestObject slot connected Emited signals count: 100000000 Total time: 108.603 Signals per second: 920784 :) Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: Dimchansky от Февраль 20, 2007, 23:38 Athlon 64 3000+
Цитировать objectCall count: 100000000 objectCall total time: 0.437 Call per second: 228832951 objectCall2 count: 100000000 objectCall2 total time: 0.688 Call2 per second: 145348837 Emited signals count: 100000000 Total time: 56.141 Signals per second: 1781229 On two slot connected Emited signals count: 100000000 Total time: 81.671 Signals per second: 1224424 TestObject slot connected Emited signals count: 100000000 Total time: 59.188 Signals per second: 1689531 только pro-файл под Windows я переделал, т.к. нифига не выводилось на экран и программа моментом выходила. Код: TEMPLATE = app Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: nova от Февраль 21, 2007, 00:43 Я вот тут переделал тест под Qt-3.3 чуть в более простом виде
object1.h Код:
object1.cpp Код:
object2.h Код:
object2.cpp Код:
main.cpp Код:
test3.pro Код:
на тойже машине результаты следуюшие Цитировать cpu: Intel(R) Core(TM)2 Duo CPU 6400@ 2.13GHz Linux bear.alba.ua 2.6.19-1.2895.fc6 #1 SMP Wed Jan 10 18:50:56 EST 2007 x86_64 x86_64 x86_64 GNU/Linux $ ./test3 Call count: 100000000 Total time: 0.291000 Call per second: 343642611 Emited count: 100000000 Total time: 3.193000 Signals per second: 31318509 Connect obj3 Emited count: 100000000 Total time: 5.629000 Signals per second: 17765144 Забавно не правдали? По этим тестам выходит что в плане выполнения вызовов через сигтал-слот qt-4.2.2 более чем в ДЕСЯТЬ раз медленнее qt-3.3.7 которая в свою очередь, более чем в ДЕСЯТЬ раз медленнее чем простой выхов метода класса :shock: Я конечно понимаю что за удобство в написании нужно платить, и я даже не против платить ДЕСЯТИКРАТНЫМ замедлением в этиз вызовах, но никак не замедлением в СТО РАЗ !!!!!!!!!!!!!!! Хотя механизм ну ОЧЕНЬ удобный :) А строчку в документайии Цитировать On an i586-500, you can emit around 2,000,000 signals per second connected to one receiver, or around 1,200,000 per second connected to two receivers троли похоже просто скопировали из qt-3.x.x :roll: Ребята, у кого с буржуйскими буквами в порядке, пните тролей этими тестами. Я к стати поковырялся в исходниках/профилерах и выяснил что основное время тратится на QMutex::lock(), QMutex::unlock() и QHashData::nextNode(). Посмотрел на эти функции так и не понял почему 8) да и тройке такого не происходит :D Я б и сам попинал, нолько у меня с ентим проблема( в смысле с буковками),понимать - все понимаю без проблем , а сказать толком нече не могу :oops: Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: Dimchansky от Февраль 21, 2007, 01:00 Просто теперь слоты стали межпоточные, поэтому видать приходится на мьютексы разоряться.
Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: куягйще от Февраль 21, 2007, 09:24 Можно еще попробывать с разными Qt::ConnectionType
Название: QT 4.2.2 Медленная работа сигнал-слот Отправлено: nova от Февраль 21, 2007, 11:22 Да мутексы и ранше использовались, и в профилере эти вызовы видны.
У меня сложилось впечетление что дело не в использовании мутексов, а в их реализации. По логике вещей функции QMutex::lock(), QMutex::unlock() и QHashData::nextNode() это простые и быстрые функции, колличество их вызовов совпвдвет с количеством итераций, но стоимость выполнения просто не реальная. |