Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Performance issues with multiple visible Windows

Performance issues with multiple visible Windows

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 2 Posters 6.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.
  • SGaistS SGaist

    The swap partition is used when application are starting to use up all amiable memory, the system then start to swap in/out memory pages between the RAM and the partition on the hard drive.

    By the way, why a QTreeView ? Are you using any feature from it ?

    Z Offline
    Z Offline
    Zmote89
    wrote on last edited by Zmote89
    #12

    @SGaist
    Ah ok, now I get what you mean with swap.

    I used QTreeView because 1) It seems to perform better, 2) the default look works in my favor (I don't want the borders of the table).

    As my current system has active 12GB ram, that shouldn't be that much of a problem. Furthermore, I once ran the application to 100'000 log entries for each of the 20 Clients and it went up to 2GB~. With the logLimit of 10'000 logs per Model memory shouldn't become much of a problem.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #13

      Wouldn't a QListView do what you want ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      Z 1 Reply Last reply
      0
      • SGaistS SGaist

        Wouldn't a QListView do what you want ?

        Z Offline
        Z Offline
        Zmote89
        wrote on last edited by
        #14

        @SGaist

        As far as I know, QListView doesn't support columns and I need columns.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #15

          For filtering or just for formatting ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          Z 1 Reply Last reply
          0
          • SGaistS SGaist

            For filtering or just for formatting ?

            Z Offline
            Z Offline
            Zmote89
            wrote on last edited by
            #16

            @SGaist

            Filtering and formatting. Some columns need to be able to be turned off and on and the "log table" needs to be able to be filter according to columns.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #17

              In your custom model, are you returning the minimal from your data method ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              Z 1 Reply Last reply
              0
              • SGaistS SGaist

                In your custom model, are you returning the minimal from your data method ?

                Z Offline
                Z Offline
                Zmote89
                wrote on last edited by
                #18

                @SGaist

                Tha's how my current data function looks in my model:

                QVariant CustomTableModel::data(const QModelIndex & index, int role) const
                {
                	if (!index.isValid())
                		return QVariant();
                
                	if (index.row() >= listOfEntries.size() || index.row() < 0)
                		return QVariant();
                
                	if (role == Qt::DisplayRole) {
                		if (index.column() < 0 || index.column() > 6)
                			return QVariant();
                		if(index.column() == 0)
                		{
                			return QString::number(index.row());
                		}
                		return listOfEntries.at(index.row()).at(index.column()-1);
                	}
                	return QVariant();
                }
                
                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #19

                  Looks good.

                  IIRC, you can avoid the QString::number call and just return index.row() or something along the lines of:

                  QVariant CustomTableModel::data(const QModelIndex & index, int role) const
                  {
                      if (!index.isValid() || role != Qt::DisplayRole)
                          return QVariant();
                  
                      const int column = index.column();
                      const int row = index.row();
                      if (column < 0 || column > 6)
                          return QVariant();
                      if(column == 0) {
                          return row;
                      } else {
                          return listOfEntries.at(row).at(column-1);
                      }
                      return QVariant();
                  }
                  

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • Z Offline
                    Z Offline
                    Zmote89
                    wrote on last edited by
                    #20

                    For those who are interested, I now how a working solution, thanks to the help of my advisors at the HSR.

                    As the main problem lay with the updating of multiple views, I first tried to change updates to bulk updates, with an updater thread signaling when to update the GUI.
                    Meaning:

                    1. A CaptureWorker in a Thread gathered logs until it was signalled by
                    2. A UpdateWorker, which in a set amount of time, sent an "update" signal to the CaptureWorker, which in turn signaled, with the logs,
                    3. RT_Main, ie., my MainWindow's handleProcessedLogs

                    This meant, that for example every 200ms multiple clients where updated at once.

                    The problem that issued from this solution, was that too many update view signals where created at the same time, which froze the GUI.

                    The new solution basically spreads the updates in the given interval on a per client basis, ie. there are still 20 Clients updated within the 200ms interval, but now they are progressively updated during the 200ms intervall and not at once every 200ms. The current solution looks like this:

                    Main Window:

                    void RT_Main::handleProcessedLogs(const QString & clientName, const QList<QList<QString>> & rows) const
                    {
                    	handleClientLog(modell.getConstClient(clientName), rows);
                    }
                    
                    void RT_Main::handleClientLog(const RT_Client& client, const QList<QList<QString>>& logs) const
                    {
                    	if (client.live())
                    	{
                    		client.addLog(logs);
                    	}
                    	if (client.toFile() || client.toRingFile())
                    	{
                    		signalToFileLog(logs, client);
                    	}
                    	if (client.getClientId() != RT_Constants::GLOBAL_ID && client.toParent())
                    	{
                    		handleClientLog(modell.getConstGroupClient(client.getGroupName()), logs);
                    	}
                    	if (client.toGlobal())
                    	{
                    		modell.globalClient.addLog(logs);
                    	}
                    }
                    
                    void RT_Main::adjustUpdateInterval()
                    {
                    	int windowCount = modell.getWindowedClientsCount();
                    	modell.updateInterval(windowCount > 1 ?
                    		RT_Constants::baseUpdateInterval + windowCount * (RT_Constants::baseUpdateInterval / 4)
                    		: RT_Constants::baseUpdateInterval);
                    }
                    

                    The adjustUpdateIntervall is called whenever a window is created or closed, there is a base Interval, ie. the lowest update frequency, whcih is at 200ms when there are no additional log windows, and gets increased with every new window (ie. UpdateWorker's signal interval ranges from 200ms to 1250ms at 0 - 20 Windows). The modell.updateInterval is thread-safe, ie. Mutex-Locked for writing. Maybe I should do one for reading as well?

                    My CaptureWorker, where logs are processed and gathered until and update signal arrives:

                    void RT_CaptureWorker::signalLogsReady()
                    {
                    	if(!entries.isEmpty())
                    	{
                    		int sleepTime = modell.updateInterval() / entries.keys().count();
                    		for (const auto & key : entries.keys()) {
                    			emit logsProcessed(key, *entries.constFind(key));
                    			QThread::msleep(sleepTime);
                    		}
                    		entries.clear();
                    	}
                    }
                    
                    void RT_CaptureWorker::handleLog(const QString & clientName, const QString & groupName, const REP::PROTO::LogMsg & msg)
                    {
                    	if (entries.contains(clientName))
                    	{
                    		entries[clientName].append(CommonLogUtils::prepareLogEntry(clientName, groupName, msg));
                    	}
                    	else
                    	{
                    		entries.insert(clientName, QList<QList<QString>>{CommonLogUtils::prepareLogEntry(clientName, groupName, msg)});
                    	}
                    }
                    

                    The UpdateWorker, which in given intervals, signals the CaptureWorker to update:

                    inline void RT_UpdateWorker::startUpdater()
                    {
                    	while(true)
                    	{
                    		emit signalUpdate();
                    		QThread::msleep(modell.updateInterval());
                    	}
                    }
                    

                    I hope this "approach" may be an inspiration for others who struggled with a similar problem. I'm open for any further improvements!

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #21

                      One other thing you might want to try: replace your 2 dimensional QList with 2 dimensional QVector.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      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