LINUX.ORG.RU

C++/Qt и callbacks - что выбрать между libsigc++, sigslot, что-то ещё?


0

5

В официальной документации по Qt в статье «Why Doesn't Qt Use Templates for Signals and Slots?» разделе «Calling Performance is Not Everything» сказано:

If you have a signals and slots connection in a tight inner loop of a performance critical task and you identify this connection as the bottleneck, think about using the standard listener-interface pattern rather than signals and slots.

Исходя из этого, я думаю, что, вместо обычных callbacks, лучше использовать библиотеки, которые реализуют типо-безопасные коллбэки.

Здесь есть неплохой список:

http://en.wikipedia.org/wiki/Observer_pattern#C.2B.2B

Лично меня заинтересовали libsigc++ и sigslot. Возможно, есть другие безопасные и в тоже время быстрые, с минимальным овэрхедом при исполнении, библиотеки реализации коллбэков?

И вообще, кто что использует, когда важна скорость, но при этом костяк приложения строится на Qt?

кто что использует, когда важна скорость

щас расскажут про asm и C, и что морду к прилржению нужно рисовать отдельно.

ukr_unix_user ★★★★
()

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

Возможно, есть другие безопасные и в тоже время быстрые

Простой listener — быстрее и безопаснее некуда.

stack_protector
()

А зачем это надо?

Чем boost::function не устраиват?

namezys ★★★★
()
Ответ на: комментарий от ukr_unix_user

Отличный мощный фреймворк с кучей плюшек, но при этом весьма шустрый.

+ Достаточно много штатных модулей, избавляющих от рутины.

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

Chaser_Andrey ★★★★★
() автор топика

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

//nanoolinux

anonymous
()
Ответ на: комментарий от Chaser_Andrey

опиши тогда конечную систему , если не сложно и не секрет.

просто есть опыт тестирования приложения на С, которое работает с большим количеством соккетов, и на разных платформах результаты значительно оличаются. И это select или pool. а демон на Qt «весьма шустрый» это как минимум спорное утверждение.

ukr_unix_user ★★★★
()
Ответ на: комментарий от Chaser_Andrey

Сори за оффтоп, но что ты используешь от кутэ в безгуевом приложении, если не секрет? Не вброса ради, просто интересно. Я вот могу припомнить QtCore - нужен в основном для поддержки сигналов-слотов и прочей чисто кутешной обвязки, сам по себе полезен мало, QtXml, который так себе и не нужен, как и сам xml, QtNetwork, который тормозной и тоже не ах, и QtScript - им я не пользовался. Еще QtSql, он неплох, но это если нужна БД. Вроде все, что из этго может потребоваться в демоне?

gaga
()
Ответ на: комментарий от m0rph

Если слушатель ровно один, то таки лучше просто boost::function, если скорость важна.

ratatosk
()
Ответ на: комментарий от gaga

В Qt есть всякие удобства типа QTcpServer, QSocket, и т.д. Но в серьезном критическом в плане производительности приложении я бы лучше boost.asio взял.

ratatosk
()
Ответ на: комментарий от gaga

QtCore - ибо есть краеугольным камнем, содержит QString, QList, QHash, QSet, QFile, QFileInfo, QDir, QIODevice в общем, QByteArray, QRegExp и ещё много других классов, которые лично я использую и они мне нужны. Сигнал-слоты приятно дополняют идиллию. А неявное разшаривание данных в почти основных классах превращает работу с памятью просто в рай.

QtSql - работаю c несколькими MySQL-базами.

QtNetwork - реализован SSL-сервер, работа идет с несколькими десятками клиентов, всё прекрасно работает в одном(!) треде, так что сделать дополнительно несколько воркеров вовсе не проблема. Если будет в разы больше абонентов - будет реализация на libev/libevent, но шансы крайне малы, ибо штат сотрудников не реально так расширить даже за пару лет.

QtXml - генерация отчётов и состояние сервера.

QtDBus - для управления сервером

QtTest для создания юнит-тестов и бенчмарков

Ещё и юзается QJson (хоть она и сторонняя) для Web-сокетов.

И это ты мне предлагаешь выбросить? А что взамен? И в чём будет профит?

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от ratatosk

Критическая производительность вовсе не в сетевом контексте.

Chaser_Andrey ★★★★★
() автор топика

Исходя из этого, я думаю, что, вместо обычных callbacks, лучше использовать библиотеки, которые реализуют типо-безопасные коллбэки.

Ты читал доку Qt, но ничего не понял. Суть в том, что с Qt тебе не нужны колюбэки. Use signals&slots, Luke.

annulen ★★★★★
()
Ответ на: комментарий от annulen

Я как раз-то читал доку. И там ясно написано, что в критических участках лучше не использовать кутешные сигналы-сокеты. Пруф находится в самом посту. Внимательно прочитай цитату и источник.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от stack_protector

Ни в чем, шило на мыло менять.

Вот именно. Так что мой выбор пал на C++/Qt.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от Chaser_Andrey

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

annulen ★★★★★
()
Ответ на: комментарий от annulen

Кхм...

http://en.wikipedia.org/wiki/Observer_pattern

Там же ссылка, например, на libsigc++

В описании libsigc++ написано следующее:

libsigc++ implements a typesafe callback system for standard C++. It allows you to define signals and to connect those signals to any callback function, either global or a member function, regardless of whether it is static or virtual.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от Chaser_Andrey

Observer разный бывает. Простейший вариант — это просто интерфейс (абстрактный класс) с виртуальными методами.

stack_protector
()
Ответ на: комментарий от Chaser_Andrey

Ну в принципе все это кроме sql и ssl есть даже в boost, а dbus и xml не нужны, но в принципе да, звучит убедительно.

Мне кажется, что если у тебя правда эти коллбэки получились узким местом, что странно, то сделай там просто тупой наблюдатель на обычных виртуальных функциях, без этих заморочек с еще одной либой. Это вполне нормальное решение по соотношению удобство/сложность сопровождения/скорость, если этим не злоупотреблять. Если, конечно, тебе не нужны полноценные сигналы, которые валятся на шину (если такое место вызывает проблемы с производительностью, то косяк в архитектуре).

gaga
()
Ответ на: комментарий от s0L

указатель на функцию, быстрее некуда

ну-ну. В случае передачи в качестве аргумента функтора, компилятор может его тело заинлайнить. Саттер приводил цифры, где коллбэки на функторах были значительно быстрее, чем на указателях.

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от DELIRIUM

Это все вилами по воде писано и в реальном проекте неотслеживаемо. Если функторов будет дохрена, они порождают кучу жирного кода, который может плохо сказываться на кэше.

gaga
()
Ответ на: комментарий от DELIRIUM

Саттер приводил цифры, где коллбэки на функторах были значительно быстрее, чем на указателях.

голословно, где цифры и логичное этому объяснение?

s0L
()
Ответ на: комментарий от stack_protector

В теории да. На практике хз что важнее, заинлайнить вызов по указателю или не засрать кэш инструкций

gaga
()
Ответ на: комментарий от gaga

В теории да. На практике хз что важнее, заинлайнить вызов по указателю или не засрать кэш инструкций

Компилятор приблизительно определит - инлайнить или нет (на основе размера кода). Стоит довериться.

Pavval ★★★★★
()
Ответ на: комментарий от stack_protector

Функторы могут заинлайниться. Вызов по указателю не может.

смысл на это надеяться? это на стадии компиляции происходит. а если мне в рантайме рулить колбэками надо, кто мне там че заинлайнит?

s0L
()
Ответ на: комментарий от s0L

Если ты передаешь функтор в шаблонную функцию, то он может заинлайнится. Иначе без вызова по указателю (или виртуального вызова что по сути то же самое) не обойтись.

stack_protector
()
Ответ на: комментарий от s0L

голословно, где цифры и логичное этому объяснение?

Логичное объяснение в том инлайне, как я сразу и написал. Собственно ЕМНИП писал он это в «Exceptional C++».

DELIRIUM ☆☆☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.