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

Performance regression on QHash::insert() and QHash::remove()

    XMLWordPrintable

Details

    • b5d480d01d (qt/qtbase/dev) b5d480d01d (qt/tqtc-qtbase/dev) 388b418e36 (qt/qtbase/6.3) 388b418e36 (qt/tqtc-qtbase/6.3)

    Description

      Run the following code in Qt 5.15 and Qt 6.

      #include <QHash>
      #include <QElapsedTimer>
      #include <QDebug>
      
      #include <unordered_map>
      
      int g_instances = 0;
      int g_liveInstances = 0;
      int g_copies = 0;
      int g_moves = 0;
      
      template <typename Value>
      class MyValue
      {
      public:
          MyValue() {
              ++g_instances;
              ++g_liveInstances;
          }
          MyValue(const Value &data) {
              m_data = data;
              ++g_instances;
              ++g_liveInstances;
          }
          ~MyValue() {
              --g_liveInstances;
          }
          MyValue(const MyValue &other) {
              m_data = other.m_data;
              ++g_instances;
              ++g_liveInstances;
              ++g_copies;
          }
          MyValue &operator=(const MyValue &other) {
              m_data = other.m_data;
              ++g_copies;
              return *this;
          }
          MyValue(MyValue &&other) {
              std::swap(m_data, other.m_data);
              ++g_instances;
              ++g_liveInstances;
              ++g_moves;
          }
          MyValue &operator=(MyValue &&other) {
              std::swap(m_data, other.m_data);
              ++g_moves;
              return *this;
          }
          Value data() const { return m_data; }
      private:
          Value m_data;
      };
      
      void printState()
      {
          qDebug() << "All instances:" << g_instances;
          qDebug() << "Live instances:" << g_liveInstances;
          qDebug() << "Copies:" << g_copies;
          qDebug() << "Moves:" << g_moves;
          qDebug() << "";
      }
      
      int main(int argc, char *argv[])
      {
          Q_UNUSED(argc);
          Q_UNUSED(argv);
          QElapsedTimer timer;
      
          using Val = MyValue<int>;
          const int maxIndex = 10000000;
      
          timer.start();
          QHash<int, Val> hash;
      
          for (int i = 0; i < maxIndex; ++i)
              hash.insert(i, Val(i));
      
          const int insertionTime = timer.elapsed();
          printState();
      
          timer.start();
          Val temp;
          for (int i = 0; i < maxIndex; ++i)
              temp = hash.value(i);
      
          const int readTime = timer.elapsed();
          printState();
      
          timer.start();
          for (int i = 0; i < maxIndex; ++i)
              hash.remove(i);
      
          const int removalTime = timer.elapsed();
          printState();
      
          qDebug() << "Insertion time:" << insertionTime << "ms. Read time:" << readTime
                   << "ms. Removal time:" << removalTime << "ms. Total time:" << (insertionTime + removalTime) << "ms.";
      
          return 0;
      }
      

      In Qt 5.15 (release build) I'm getting the following result:

      All instances: 20000000
      Live instances: 10000000
      Copies: 10000000
      Moves: 0
      
      All instances: 30000001
      Live instances: 10000001
      Copies: 30000000
      Moves: 0
      
      All instances: 30000001
      Live instances: 1
      Copies: 30000000
      Moves: 0
      
      Insertion time: 462 ms. Read time: 41 ms. Removal time: 232 ms. Total time: 694 ms.
      

      While in 6.1 (release build) I'm getting this:

      All instances: 81663592
      Live instances: 10000000
      Copies: 10000000
      Moves: 61663592
      
      All instances: 101663593
      Live instances: 10000001
      Copies: 20000000
      Moves: 71663592
      
      All instances: 101680302
      Live instances: 1
      Copies: 20000000
      Moves: 71680301
      
      Insertion time: 1638 ms. Read time: 429 ms. Removal time: 1783 ms. Total time: 3421 ms.
      

      Attachments

        Issue Links

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

          Activity

            People

              thiago Thiago Macieira
              jkobus Jarek Kobus
              Votes:
              0 Vote for this issue
              Watchers:
              10 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: