Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-54180

QPainter drawText() combined with setFont() very slow

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P1: Critical
    • Resolution: Done
    • Affects Version/s: 5.6.0, 5.6.1, 5.7.0
    • Fix Version/s: 5.6.2
    • Component/s: GUI: Painting
    • Labels:
      None
    • Commits:
      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();
      }
      

        Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

            Assignee:
            esabraha Eskil Abrahamsen Blomfeldt
            Reporter:
            mireiner Chris
            Votes:
            1 Vote for this issue
            Watchers:
            9 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes