Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. Qt 6
  4. Qt6 Windows slower than Qt6 Ubuntu
Forum Updated to NodeBB v4.3 + New Features

Qt6 Windows slower than Qt6 Ubuntu

Scheduled Pinned Locked Moved Solved Qt 6
ubuntuwindows 10 instmsvcgccqt6
47 Posts 5 Posters 8.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Joe von Habsburg

    @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

    After a while crashing :(

    I found the reason. Because readReady() sometimes receives incomplete data.

    jsulmJ Offline
    jsulmJ Offline
    jsulm
    Lifetime Qt Champion
    wrote on last edited by
    #34

    @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

    sometimes receives incomplete data

    Yes, because there is no guarantee that you get all data in one piece. That's why you need to buffer incoming data until you received a whole package of data.

    https://forum.qt.io/topic/113070/qt-code-of-conduct

    Christian EhrlicherC J 2 Replies Last reply
    1
    • jsulmJ jsulm

      @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

      sometimes receives incomplete data

      Yes, because there is no guarantee that you get all data in one piece. That's why you need to buffer incoming data until you received a whole package of data.

      Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #35

      @jsulm... or use the requestFinished signal 🙂

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      2
      • jsulmJ jsulm

        @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

        sometimes receives incomplete data

        Yes, because there is no guarantee that you get all data in one piece. That's why you need to buffer incoming data until you received a whole package of data.

        J Offline
        J Offline
        Joe von Habsburg
        wrote on last edited by Joe von Habsburg
        #36

        @jsulm said in Qt6 Windows slower than Qt6 Ubuntu:

        Yes, because there is no guarantee that you get all data in one piece. That's why you need to buffer incoming data until you received a whole package of data.

        Yes, I try downloadProgress signal like that:

        void DataReceiver::downloadProgressSample(qint64 bytesReceived, qint64 bytesTotal)
        {
            if(bytesReceived == bytesTotal){
                _isSampleOk = true;
                _sampleLen = bytesReceived;
            }
            else{
                _isSampleOk = false;
                _sampleLen = 0;
            }
        }
        

        but so many times, my QByteArray's length and bytesReceived are not equal.... and my program slowing for that.

        @Christian-Ehrlicher said in Qt6 Windows slower than Qt6 Ubuntu:

        or use the requestFinished signal

        I could not see requestFinished signal on documentation. Do you mean say finished signal ?

        jsulmJ JonBJ 2 Replies Last reply
        0
        • J Joe von Habsburg

          @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

          After a while crashing :(

          I found the reason. Because readReady() sometimes receives incomplete data.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #37

          @Joe-von-Habsburg
          Exactly as my colleagues have replied above for readyRead().

          If you are still pursuing the difference in memory usage you report. A couple of points about your code:

          You have a couple of calls to getData() inside some loop, while (_takeData). Your getData() uses (or used to use, you may have changed that now) _reply->deleteLater(). Although you have a QEventLoop::exec() call, which will allow signals/slots to flow, this is not the top-level Qt event loop. I believe deleteLater() causes deferred deletes, meaning that the memory is not actually released until the top-level event loop is re-entered. You should not use a while loop like this for your tests: allow the top-level Qt event loop to be re-entered.

          getData() returns a QByteArray. We do not know what your code does with that result: for all we know you retain that somewhere, and that would eat up memory.

          To investigate properly you should produce a minimal reproducible example with "good" code, to be sure what you are looking at.

          1 Reply Last reply
          0
          • J Joe von Habsburg

            @jsulm said in Qt6 Windows slower than Qt6 Ubuntu:

            Yes, because there is no guarantee that you get all data in one piece. That's why you need to buffer incoming data until you received a whole package of data.

            Yes, I try downloadProgress signal like that:

            void DataReceiver::downloadProgressSample(qint64 bytesReceived, qint64 bytesTotal)
            {
                if(bytesReceived == bytesTotal){
                    _isSampleOk = true;
                    _sampleLen = bytesReceived;
                }
                else{
                    _isSampleOk = false;
                    _sampleLen = 0;
                }
            }
            

            but so many times, my QByteArray's length and bytesReceived are not equal.... and my program slowing for that.

            @Christian-Ehrlicher said in Qt6 Windows slower than Qt6 Ubuntu:

            or use the requestFinished signal

            I could not see requestFinished signal on documentation. Do you mean say finished signal ?

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #38

            @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

            Yes, I try downloadProgress signal like that

            What does this have to do with buffering incoming data?
            To get a simpler solution follow @Christian-Ehrlicher suggestion.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • J Joe von Habsburg

              @jsulm said in Qt6 Windows slower than Qt6 Ubuntu:

              Yes, because there is no guarantee that you get all data in one piece. That's why you need to buffer incoming data until you received a whole package of data.

              Yes, I try downloadProgress signal like that:

              void DataReceiver::downloadProgressSample(qint64 bytesReceived, qint64 bytesTotal)
              {
                  if(bytesReceived == bytesTotal){
                      _isSampleOk = true;
                      _sampleLen = bytesReceived;
                  }
                  else{
                      _isSampleOk = false;
                      _sampleLen = 0;
                  }
              }
              

              but so many times, my QByteArray's length and bytesReceived are not equal.... and my program slowing for that.

              @Christian-Ehrlicher said in Qt6 Windows slower than Qt6 Ubuntu:

              or use the requestFinished signal

              I could not see requestFinished signal on documentation. Do you mean say finished signal ?

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #39

              @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

              but so many times, my QByteArray's length and bytesReceived are not equal.... and my program slowing for that.

              I don't understand your point or question here? If you readyRead() as you go along or use QNetworkReply::downloadProgress() you will (almost certainly) see data arrive in "chunks", i.e. multiple calls until all the data is received. That is how the data is being transmitted, and is quite normal/expected.

              As I wrote earlier, if you do not want to handle partial data as it arrives, and are using reply auto-delete so you cannot access it after it has finished, you can place a slot on QNetworkReply::finished and readAll() the data there in one go, before allowing the reply to be deleted.

              J 1 Reply Last reply
              1
              • JonBJ JonB

                @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

                but so many times, my QByteArray's length and bytesReceived are not equal.... and my program slowing for that.

                I don't understand your point or question here? If you readyRead() as you go along or use QNetworkReply::downloadProgress() you will (almost certainly) see data arrive in "chunks", i.e. multiple calls until all the data is received. That is how the data is being transmitted, and is quite normal/expected.

                As I wrote earlier, if you do not want to handle partial data as it arrives, and are using reply auto-delete so you cannot access it after it has finished, you can place a slot on QNetworkReply::finished and readAll() the data there in one go, before allowing the reply to be deleted.

                J Offline
                J Offline
                Joe von Habsburg
                wrote on last edited by
                #40

                @jsulm said in Qt6 Windows slower than Qt6 Ubuntu:

                What does this have to do with buffering incoming data?
                To get a simpler solution follow @Christian-Ehrlicher suggestion.

                I could not see requestFinished signal on documentation. Do you mean say "finished" signal ?

                @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                don't understand your point or question here?

                My question is that. if I use "finished" signal memory leak.

                @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                _reply->readyRead()

                You suggested to me "readyRead" signal but now, I could not readyAll because, incomplated data is received.

                For example, data's size must be 350000, but i receive 348000 or less. As a result of for that I crashed.

                @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                QNetworkReply::downloadProgress()

                I try check will have arrived data size use with "downloadProgress" signal and my QByteArray data size is equal ? but so many times thay are not.

                How can I wait all data complate without use "finished" signal because memory leak?

                @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                As I wrote earlier, if you do not want to handle partial data as it arrives, and are using reply auto-delete so you cannot access it after it has finished, you can place a slot on QNetworkReply::finished and readAll() the data there in one go, before allowing the reply to be deleted.

                I don't understand. Can you give me code example ?

                jsulmJ JonBJ 2 Replies Last reply
                0
                • J Joe von Habsburg

                  @jsulm said in Qt6 Windows slower than Qt6 Ubuntu:

                  What does this have to do with buffering incoming data?
                  To get a simpler solution follow @Christian-Ehrlicher suggestion.

                  I could not see requestFinished signal on documentation. Do you mean say "finished" signal ?

                  @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                  don't understand your point or question here?

                  My question is that. if I use "finished" signal memory leak.

                  @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                  _reply->readyRead()

                  You suggested to me "readyRead" signal but now, I could not readyAll because, incomplated data is received.

                  For example, data's size must be 350000, but i receive 348000 or less. As a result of for that I crashed.

                  @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                  QNetworkReply::downloadProgress()

                  I try check will have arrived data size use with "downloadProgress" signal and my QByteArray data size is equal ? but so many times thay are not.

                  How can I wait all data complate without use "finished" signal because memory leak?

                  @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                  As I wrote earlier, if you do not want to handle partial data as it arrives, and are using reply auto-delete so you cannot access it after it has finished, you can place a slot on QNetworkReply::finished and readAll() the data there in one go, before allowing the reply to be deleted.

                  I don't understand. Can you give me code example ?

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #41

                  @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

                  You suggested to me "readyRead" signal but now, I could not readyAll because, incomplated data is received

                  As already suggested: you need to accumulate incoming data in a buffer. readyRead() signal can be emited several times until you get everything.

                  "Do you mean say "finished" signal ?" - yes
                  https://doc.qt.io/qt-6/qnetworkreply.html#finished
                  It even explains: "In particular, if no calls to read() were made as a result of readyRead(), a call to readAll() will retrieve the full contents in a QByteArray."

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  J 1 Reply Last reply
                  1
                  • jsulmJ jsulm

                    @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

                    You suggested to me "readyRead" signal but now, I could not readyAll because, incomplated data is received

                    As already suggested: you need to accumulate incoming data in a buffer. readyRead() signal can be emited several times until you get everything.

                    "Do you mean say "finished" signal ?" - yes
                    https://doc.qt.io/qt-6/qnetworkreply.html#finished
                    It even explains: "In particular, if no calls to read() were made as a result of readyRead(), a call to readAll() will retrieve the full contents in a QByteArray."

                    J Offline
                    J Offline
                    Joe von Habsburg
                    wrote on last edited by Joe von Habsburg
                    #42

                    @jsulm said in Qt6 Windows slower than Qt6 Ubuntu:

                    As already suggested: you need to accumulate incoming data in a buffer. readyRead() signal can be emited several times until you get everything.

                    Hmm now I should not assign reply->readAll(), I should append :). I will try it.

                    _sample.append(_replySample->readAll());
                    

                    @jsulm said in Qt6 Windows slower than Qt6 Ubuntu:

                    "Do you mean say "finished" signal ?" - yes

                    I cannot use it because memory leak.

                    jsulmJ 1 Reply Last reply
                    0
                    • J Joe von Habsburg

                      @jsulm said in Qt6 Windows slower than Qt6 Ubuntu:

                      What does this have to do with buffering incoming data?
                      To get a simpler solution follow @Christian-Ehrlicher suggestion.

                      I could not see requestFinished signal on documentation. Do you mean say "finished" signal ?

                      @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                      don't understand your point or question here?

                      My question is that. if I use "finished" signal memory leak.

                      @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                      _reply->readyRead()

                      You suggested to me "readyRead" signal but now, I could not readyAll because, incomplated data is received.

                      For example, data's size must be 350000, but i receive 348000 or less. As a result of for that I crashed.

                      @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                      QNetworkReply::downloadProgress()

                      I try check will have arrived data size use with "downloadProgress" signal and my QByteArray data size is equal ? but so many times thay are not.

                      How can I wait all data complate without use "finished" signal because memory leak?

                      @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                      As I wrote earlier, if you do not want to handle partial data as it arrives, and are using reply auto-delete so you cannot access it after it has finished, you can place a slot on QNetworkReply::finished and readAll() the data there in one go, before allowing the reply to be deleted.

                      I don't understand. Can you give me code example ?

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by kshegunov
                      #43

                      @Joe-von-Habsburg
                      As @jsulm has said. With QNetworkAccessManager::setAutoDeleteReplies(true) set you should be able to use either of the following approaches:

                      QByteArray _bytesRead;    // class member variable
                      
                      _bytesRead.clear();
                      connect(_reply, &QNetworkReply::finished, this, &Class::onFinished);
                      _reply = _manager.get(_request);
                      
                      void Class::onFinished()
                      {
                          _bytesRead = _reply->readAll();    // read all bytes in one go at the end, just before `_reply` gets auto-deleted
                      }
                      

                      or

                      QByteArray _bytesRead;    // class member variable
                      
                      _bytesRead.clear();
                      connect(_reply, &QNetworkReply::readyRead, this, &Class::onReadyRead);
                      connect(_reply, &QNetworkReply::finished, this, &Class::onFinished);
                      _reply = _manager.get(_request);
                      
                      void Class::onReadyRead()
                      {
                          _bytesRead += _reply->readAll();    // *append* this time's bytes read to buffer
                      }
                      
                      void Class::onFinished()
                      {
                          // I think `_bytesRead` should contain all data by now, when reply has finished
                          // If not call `_bytesRead += _reply->readAll();` or `onReadyRead()` one last time
                      }
                      

                      [Edit: Fixed code highlighting ~kshegunov]

                      J 1 Reply Last reply
                      2
                      • J Joe von Habsburg

                        @jsulm said in Qt6 Windows slower than Qt6 Ubuntu:

                        As already suggested: you need to accumulate incoming data in a buffer. readyRead() signal can be emited several times until you get everything.

                        Hmm now I should not assign reply->readAll(), I should append :). I will try it.

                        _sample.append(_replySample->readAll());
                        

                        @jsulm said in Qt6 Windows slower than Qt6 Ubuntu:

                        "Do you mean say "finished" signal ?" - yes

                        I cannot use it because memory leak.

                        jsulmJ Offline
                        jsulmJ Offline
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #44

                        @Joe-von-Habsburg said in Qt6 Windows slower than Qt6 Ubuntu:

                        cannot use it because memory leak.

                        There should not be memory leak unless your code is wrong.
                        Simply connect a slot to finished() signal and in that slot call readAll() and deleteLater() on the reply.

                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        2
                        • JonBJ JonB

                          @Joe-von-Habsburg
                          As @jsulm has said. With QNetworkAccessManager::setAutoDeleteReplies(true) set you should be able to use either of the following approaches:

                          QByteArray _bytesRead;    // class member variable
                          
                          _bytesRead.clear();
                          connect(_reply, &QNetworkReply::finished, this, &Class::onFinished);
                          _reply = _manager.get(_request);
                          
                          void Class::onFinished()
                          {
                              _bytesRead = _reply->readAll();    // read all bytes in one go at the end, just before `_reply` gets auto-deleted
                          }
                          

                          or

                          QByteArray _bytesRead;    // class member variable
                          
                          _bytesRead.clear();
                          connect(_reply, &QNetworkReply::readyRead, this, &Class::onReadyRead);
                          connect(_reply, &QNetworkReply::finished, this, &Class::onFinished);
                          _reply = _manager.get(_request);
                          
                          void Class::onReadyRead()
                          {
                              _bytesRead += _reply->readAll();    // *append* this time's bytes read to buffer
                          }
                          
                          void Class::onFinished()
                          {
                              // I think `_bytesRead` should contain all data by now, when reply has finished
                              // If not call `_bytesRead += _reply->readAll();` or `onReadyRead()` one last time
                          }
                          

                          [Edit: Fixed code highlighting ~kshegunov]

                          J Offline
                          J Offline
                          Joe von Habsburg
                          wrote on last edited by
                          #45

                          @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                          QByteArray _bytesRead; // class member variable

                          _bytesRead.clear();
                          connect(_reply, &QNetworkReply::readyRead, this, &Class::onReadyRead);
                          connect(_reply, &QNetworkReply::finished, this, &Class::onFinished);
                          _reply = _manager.get(_request);

                          void Class::onReadyRead()
                          {
                          _bytesRead += _reply->readAll(); // append this time's bytes read to buffer
                          }

                          void Class::onFinished()
                          {
                          // I think _bytesRead should contain all data by now, when reply has finished
                          // If not call _bytesRead += _reply->readAll(); or onReadyRead() one last time
                          }

                          its work !!! Thank you so much

                          JonBJ 1 Reply Last reply
                          0
                          • J Joe von Habsburg has marked this topic as solved on
                          • J Joe von Habsburg

                            @JonB said in Qt6 Windows slower than Qt6 Ubuntu:

                            QByteArray _bytesRead; // class member variable

                            _bytesRead.clear();
                            connect(_reply, &QNetworkReply::readyRead, this, &Class::onReadyRead);
                            connect(_reply, &QNetworkReply::finished, this, &Class::onFinished);
                            _reply = _manager.get(_request);

                            void Class::onReadyRead()
                            {
                            _bytesRead += _reply->readAll(); // append this time's bytes read to buffer
                            }

                            void Class::onFinished()
                            {
                            // I think _bytesRead should contain all data by now, when reply has finished
                            // If not call _bytesRead += _reply->readAll(); or onReadyRead() one last time
                            }

                            its work !!! Thank you so much

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by
                            #46

                            @Joe-von-Habsburg
                            Do your timings/memory consumption with this asynchronous approach (i.e. no _loop.exec()) and not with that original while() loop. (If you want to run it more than once, after you get finished() on one start the next one there or on a QTimer::singleShot().) See whether you still get bad performance on one versus the other.

                            J 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @Joe-von-Habsburg
                              Do your timings/memory consumption with this asynchronous approach (i.e. no _loop.exec()) and not with that original while() loop. (If you want to run it more than once, after you get finished() on one start the next one there or on a QTimer::singleShot().) See whether you still get bad performance on one versus the other.

                              J Offline
                              J Offline
                              Joe von Habsburg
                              wrote on last edited by
                              #47

                              @JonB

                              Last edit my code :

                              DataReceiver::DataReceiver(QObject *parent)
                                 : QObject{parent}
                              {
                                 _manager.setAutoDeleteReplies(true);
                              }
                              void DataReceiver::start()
                              {
                                 _connection++;
                                 if(_connection > 1)
                                     return;
                              
                                 _takeData = true;
                                 run();
                              }
                              
                              void DataReceiver::stop()
                              {
                                 _takeData = false;
                                 _connection = 0;
                                 _data.clear();
                              }
                              
                              
                              void DataReceiver::getData()
                              {
                                 _data.clear();
                                 QString url = QString("http://localhost:%1/sample").arg(_port);
                                 QUrl _apiUrl(url);
                                 QNetworkRequest _request(_apiUrl);
                                 _reply = _manager.get(_request);
                                 connect(_reply, &QNetworkReply::readyRead, this, &DataReceiver::onReadReady);
                                 connect(_reply, &QNetworkReply::finished, this, &DataReceiver::onFinished);
                              }
                              
                              
                              void DataReceiver::run()
                              {
                                 if(!_takeData)
                                     return;
                              
                                 getData();
                              }
                              
                              void DataReceiver::onReadReady()
                              {
                                 _data += _reply->readAll();
                              }
                              
                              void DataReceiver::onFinished()
                              {
                                 emit sendData(_data);
                                 run();
                              }
                              

                              its working. time slow down from 65ms to 165ms but its working.

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved