ich scanne gerade verschiedene platformen fuer ein projekt bei dem schnelle reaktionszeiten auf netzwerk daten sehr wichtig ist. Dabei bin ich auch auf Qt gestossen und ein paar kleinere tests geschrieben. Der basis test ist ein UDP ping bei dem round trips pro sekunde gemessen werden. Qt auf Windows hat dabei sehr schlecht abgeschnitten, zum vergleich mal die ergebnisse:
Qt windows: 1000 (700 mit GUI update) messages per second
.NET windows: 2600 (1200 mit GUI update) messages per second
ACE Windows: 3800 messages per second
Qt linux: 4200 (400 mit GUI update) messages per second
ACE Linux: 8000 messages per second
Ich frage mich warum Qt unter windows so schlecht abschneidet, gibt es eventuell einen 1ms timer der nach jedem packet erst mal abgewarted wird um windows messages abzufragen? Das wuerde in etwa die 1000 messages pro sekunde erklaeren. Wenn dem so ist, kann man diesen timer umgehen? Und/oder kann man asynchrone windows sockets integrieren?
Qt unter X sieht zwar auf den ersten blick ganz gut aus, aber wenn man irgendwas anzeigen will wird man voll ausgebremst.
Als test applikation habe ich den broadcastreceiver aus den examples genommen und lediglich einen timer sowie paket zaehler eingefuegt.
Der code als referenz:
Code: Alles auswählen
Receiver::Receiver(QWidget *parent)
: QDialog(parent)
{
statusLabel = new QLabel(tr("Listening"));
pktPerSecLabel = new QLabel(tr("0"));
quitButton = new QPushButton(tr("&Quit"));
startButton = new QPushButton(tr("&Start"));
lineEdit = new QLineEdit(tr("10.60.67.197"), parent);
pktPerSecLabel->setFrameStyle(QFrame::StyledPanel);
pktPerSecLabel->setFrameShadow(QFrame::Shadow::Sunken);
statusLabel->setFrameStyle(QFrame::StyledPanel);
statusLabel->setFrameShadow(QFrame::Shadow::Sunken);
udpSocket = new QUdpSocket(this);
udpSocket->bind(12889);
nPackets = 0;
connect(udpSocket, SIGNAL(readyRead()),
this, SLOT(processPendingDatagrams()));
connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
connect(startButton, SIGNAL(clicked()), this, SLOT(sendPingDgram()));
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(1);
buttonLayout->addWidget(quitButton);
buttonLayout->addWidget(startButton);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(statusLabel);
mainLayout->addWidget(pktPerSecLabel);
mainLayout->addWidget(lineEdit);
mainLayout->addLayout(buttonLayout);
setLayout(mainLayout);
setWindowTitle(tr("Broadcast Receiver"));
timer = new QTimer(parent);
connect(timer,SIGNAL(timeout()), this, SLOT(timerProc()));
}
void Receiver::timerProc()
{
static int nCalls = 0;
nCalls++;
QString st;
int packetsPerSec = nPackets / (nCalls*10);
st.sprintf("%i", packetsPerSec);
pktPerSecLabel->setText(st);
}
void Receiver::processPendingDatagrams()
{
while (udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
char buffer[1024];
QHostAddress addr;
quint16 port;
qint64 nBytes;
nBytes = udpSocket->readDatagram(buffer, 1024, &addr, & port);
//datagram.resize(udpSocket->pendingDatagramSize());
//udpSocket->readDatagram(datagram.data(), datagram.size(), & addr, & port);
nPackets ++;
QString st;
//st.sprintf("%i",nPackets); // uncomment to test GUI update speed
//statusLabel->setText(st);
udpSocket->writeDatagram(buffer, nBytes, addr, port);
}
}
void Receiver::sendPingDgram()
// called once to initiate the ping loop
{
QString text = lineEdit->text();
QHostAddress host;
QByteArray dgram;
qint16 port;
port = 12889;
host.setAddress(text);
dgram.clear();
dgram.append("1234567890");
udpSocket->writeDatagram(dgram, host, port);
timer->start(10000);
}