Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
5.6.0, 5.6.1, 5.7.0
-
None
-
49926bb9ef983d4c19aed635a00b388252c065e4
Description
Qt 5.6.0, Qt 5.6.1 or Qt 5.7.0:
Multiple calls of QPainter::drawText() each with a different font set with QPainter::setFont(), running as moving graphic animation to show its performance speed, is multiple times slower than the same code build with Qt 5.4.2, Qt 5.5.0 and Qt 5.5.1.
Tested on Windows 10 64bit as a C++ QWidget desktop application. The slow down happens with MinGW 32bit, MSVC 32bit and 64bit compiled Qt versions.
My hardware:
CPU: Intel Core 2 Duo E8400 @3.00GHz
RAM: 8GB Dual Channal DDR2 @445MHz (5-5-5-15)
Graphic card: ATI Radeon HD 3600 512MB (Directx 10.1 - non Gamer card)
Harddrive: Samsung Evo Pro 850 512GB
Operating System:
Windows 10 Pro 64bit Build (Version 1511 Build 10586.420)
Compiler:
Visual Studio 2013 Update 5
The provided example code (see below) runs on my machine:
-----------------------------------------
QT 5.5.1_x64 VS_2013
Debug
Test1 ( 1 font ): 5.243 seconds
Test2 (13 fonts): 5.200 seconds
Test3 ( 4 fonts): 5.249 seconds
Test4 ( 3 fonts): 5.470 seconds
Release
Test1 ( 1 font ): 3.791 seconds
Test2 (13 fonts): 3.880 seconds
Test3 ( 4 fonts): 3.879 seconds
Test4 ( 3 fonts): 3.944 seconds
------------------------------------------
QT 5.6.1-1_x64 VS_2013
Debug
Test1 ( 1 font ): 5.291 seconds
Test2 (13 fonts): 43.682 seconds ==> slow
Test3 ( 4 fonts): 24.804 seconds ==> slow
Test4 ( 3 fonts): 5.834 seconds
Release
Test1 ( 1 font ): 3.773 seconds
Test2 (13 fonts): 20.354 seconds ==> slow
Test3 ( 4 fonts): 13.592 seconds ==> slow
Test4 ( 3 fonts): 4.009 seconds
------------------------------------------
Please compile this example code with Qt 5.5.1 or prior version and Qt 5.6.0 or later version for comparison to see the bug in action:
#include <QApplication> #include <QWidget> #include <QPainter> #include <QElapsedTimer> class Widget : public QWidget { public: Widget(); protected: void timerEvent(QTimerEvent *event); void paintEvent(QPaintEvent *); private: QElapsedTimer elapsedTimer; int timerId; int elapsedTime1, elapsedTime2, elapsedTime3, elapsedTime4; bool isFinished1, isFinished2, isFinished3, isFinished4, isFinished5; int i, x1, x2, x3, x4, y1, y2, y3, y4; static QFont Arial, Caladea, Tomaha, Consolas, Calibri, Impact; static QFont Courier_New, Gorgia, Verdana, Times_New_Roman; static QFont Microsoft_Sans_Serif, Segoe_UI, Trebuchet_MS; }; QFont Widget::Arial("Arial", 14); QFont Widget::Caladea("Caladea", 14); QFont Widget::Tomaha("Tomaha", 14); QFont Widget::Consolas("Consolas", 14); QFont Widget::Calibri("Calibri", 14); QFont Widget::Impact("Impact", 14); QFont Widget::Segoe_UI("Segoe UI", 14); QFont Widget::Gorgia("Gorgia", 14); QFont Widget::Verdana("Verdana", 14); QFont Widget::Trebuchet_MS("Trebuchet MS", 14); QFont Widget::Courier_New("Courier New", 14); QFont Widget::Times_New_Roman("Times New Roman", 14); QFont Widget::Microsoft_Sans_Serif("Microsoft Sans Serif", 14); Widget::Widget() { setAutoFillBackground(true); setPalette(Qt::white); timerId = startTimer(1); elapsedTimer.start(); i=0; x1=0; x2=0, x3=0, x4=0; isFinished1 = isFinished2 = isFinished3 = isFinished4 = isFinished5 = false; } void Widget::timerEvent(QTimerEvent* /* event */) { update(); } void Widget::paintEvent(QPaintEvent *) { QPainter painter(this); if (i > 0 && i < 800) { y1 = 10; painter.setFont(Arial); painter.drawText(x1, y1 += 30, "Test 1"); painter.drawText(x1, y1 += 30, "row 01"); painter.drawText(x1, y1 += 30, "row 02"); painter.drawText(x1, y1 += 30, "row 03"); painter.drawText(x1, y1 += 30, "row 04"); painter.drawText(x1, y1 += 30, "row 05"); painter.drawText(x1, y1 += 30, "row 06"); painter.drawText(x1, y1 += 30, "row 07"); painter.drawText(x1, y1 += 30, "row 08"); painter.drawText(x1, y1 += 30, "row 09"); painter.drawText(x1, y1 += 30, "row 10"); painter.drawText(x1, y1 += 30, "row 11"); painter.drawText(x1, y1 += 30, "row 12"); x1++; elapsedTime1 = elapsedTimer.elapsed(); } else if (i > 800 && i < 1600) { isFinished1 = true; y2 = 160; painter.setFont(Arial); painter.drawText(x2, y2 += 30, "Test 2"); painter.setFont(Caladea); painter.drawText(x2, y2 += 30, "row 01"); painter.setFont(Tomaha); painter.drawText(x2, y2 += 30, "row 02"); painter.setFont(Consolas); painter.drawText(x2, y2 += 30, "row 03"); painter.setFont(Calibri); painter.drawText(x2, y2 += 30, "row 04"); painter.setFont(Impact); painter.drawText(x2, y2 += 30, "row 05"); painter.setFont(Segoe_UI); painter.drawText(x2, y2 += 30, "row 06"); painter.setFont(Gorgia); painter.drawText(x2, y2 += 30, "row 07"); painter.setFont(Verdana); painter.drawText(x2, y2 += 30, "row 08"); painter.setFont(Trebuchet_MS); painter.drawText(x2, y2 += 30, "row 09"); painter.setFont(Courier_New); painter.drawText(x2, y2 += 30, "row 10"); painter.setFont(Times_New_Roman); painter.drawText(x2, y2 += 30, "row 11"); painter.setFont(Microsoft_Sans_Serif); painter.drawText(x2, y2 += 30, "row 12"); x2++; elapsedTime2 = elapsedTimer.elapsed(); } else if (i > 1600 && i < 2400) { isFinished2 = true; y3 = 310; painter.setFont(Arial); painter.drawText(x3, y3 += 30, "Test 3"); painter.drawText(x3, y3 += 30, "row 01"); painter.drawText(x3, y3 += 30, "row 02"); painter.drawText(x3, y3 += 30, "row 03"); painter.setFont(Consolas); painter.drawText(x3, y3 += 30, "row 04"); painter.drawText(x3, y3 += 30, "row 05"); painter.drawText(x3, y3 += 30, "row 06"); painter.setFont(Impact); painter.drawText(x3, y3 += 30, "row 07"); painter.drawText(x3, y3 += 30, "row 08"); painter.drawText(x3, y3 += 30, "row 09"); painter.setFont(Courier_New); painter.drawText(x3, y3 += 30, "row 10"); painter.drawText(x3, y3 += 30, "row 11"); painter.drawText(x3, y3 += 30, "row 12"); x3++; elapsedTime3 = elapsedTimer.elapsed(); } else if (i > 2400 && i < 3200) { isFinished3 = true; y4 = 460; painter.setFont(Arial); painter.drawText(x4, y4 += 30, "Test 4"); painter.drawText(x4, y4 += 30, "row 01"); painter.drawText(x4, y4 += 30, "row 02"); painter.drawText(x4, y4 += 30, "row 03"); painter.drawText(x4, y4 += 30, "row 04"); painter.setFont(Impact); painter.drawText(x4, y4 += 30, "row 05"); painter.drawText(x4, y4 += 30, "row 06"); painter.drawText(x4, y4 += 30, "row 07"); painter.drawText(x4, y4 += 30, "row 08"); painter.setFont(Courier_New); painter.drawText(x4, y4 += 30, "row 09"); painter.drawText(x4, y4 += 30, "row 10"); painter.drawText(x4, y4 += 30, "row 11"); painter.drawText(x4, y4 += 30, "row 12"); x4++; elapsedTime4 = elapsedTimer.elapsed(); } else if (i > 3200) { isFinished4 = true; } i++; if (isFinished1) { painter.setFont(QFont("Arial", 12.0, QFont::Bold)); painter.drawText(QPoint(200, 100), "Test1 (1 font) elapsed time in seconds: " + QString::number(elapsedTime1/1000.0)); } if (isFinished2) { painter.drawText(QPoint(200, 200), "Test2 (12 fonts) elapsed time in seconds: " + QString::number((elapsedTime2-elapsedTime1)/1000.0)); } if (isFinished3) { painter.drawText(QPoint(200, 300), "Test3 (4 fonts) elapsed time in seconds: " + QString::number((elapsedTime3-elapsedTime2)/1000.0)); } if (isFinished4) { painter.drawText(QPoint(200, 400), "Test4 (3 fonts) elapsed time in seconds: " + QString::number((elapsedTime4-elapsedTime3)/1000.0)); } } int main(int argc, char *argv[]) { QApplication app(argc, argv); Widget widget; widget.showMaximized(); return app.exec(); }