Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
qtws26_logo

The Qt Event of the Year: Qt World Summit 2026

Save Your Spot >
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QVariant conversions (.toString() .toInt()) performance.
Qt 6.12 LTS is out! See what's new in the release blog

QVariant conversions (.toString() .toInt()) performance.

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 4 Posters 6.0k Views 1 Watching
  • 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.
  • M Offline
    M Offline
    Mike Fidel
    wrote on last edited by
    #1

    Greetings.

    I wanted to ask if there is a significant performance overhead when using `QVariant' conversion methods. For example if there is a significant difference in performance when using:

    QVariant var = QVariant("MyString");
    
    qDebug() << var.toString();
    
    

    Versus

    QString str = "MyString";
    
    qDebug() << str;
    

    I'm more interested in the performance impact of the conversion operation .toString() , .toInt() etc than the object instantiation.

    jsulmJ 1 Reply Last reply
    0
    • M Mike Fidel

      Greetings.

      I wanted to ask if there is a significant performance overhead when using `QVariant' conversion methods. For example if there is a significant difference in performance when using:

      QVariant var = QVariant("MyString");
      
      qDebug() << var.toString();
      
      

      Versus

      QString str = "MyString";
      
      qDebug() << str;
      

      I'm more interested in the performance impact of the conversion operation .toString() , .toInt() etc than the object instantiation.

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

      @Mike-Fidel You could write a simple benchmark to measure the difference.
      I think var.toString() will be slower as it creates a new QString instance each time it is called.

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

      1 Reply Last reply
      4
      • M Offline
        M Offline
        Mike Fidel
        wrote on last edited by Mike Fidel
        #3

        @jsulm This is the benchmark I did:

        int main(int argc, char *argv[])
        {
            QElapsedTimer variantTimer;
            QElapsedTimer stringTimer;
        
            QVariant var = QVariant("My String");
        
            QString string = "My String";
        
        
        
            QString stringTest;
            QString varTest;
        
        
            stringTimer.start();
            for (int i = 0 ; i < 100000 ; i++)
            {
                  stringTest = string;
            }
        
            std::cout << "string  took " << stringTimer.nsecsElapsed() << " nano seconds " << std::endl;
        
        
        
            variantTimer.start();
            for (int i = 0 ; i < 100000 ; i++)
            {
                varTest = var.toString();
            }
        
            std::cout << "Variant took " << variantTimer.nsecsElapsed() << " nano seconds " << std::endl;
        
        
        }
        

        Output I got:

        string took 2084675 nano seconds
        Variant took 4343839 nano seconds

        However if you include the deceleration of QString inside the loop like so:

        int main(int argc, char *argv[])
        {
            QElapsedTimer variantTimer;
            QElapsedTimer stringTimer;
        
            QVariant var = QVariant("My String");
        
            QString string = "My String";
        
        
        
            //QString stringTest;
            //QString varTest;
        
        
            stringTimer.start();
            for (int i = 0 ; i < 100000 ; i++)
            {
                  QString stringTest = string;
            }
        
            std::cout << "string  took " << stringTimer.nsecsElapsed() << " nano seconds " << std::endl;
        
        
        
            variantTimer.start();
            for (int i = 0 ; i < 100000 ; i++)
            {
                QString varTest = var.toString();
            }
        
            std::cout << "Variant took " << variantTimer.nsecsElapsed() << " nano seconds " << std::endl;
        
        
        }
        
        
        

        I get the following output:

        string took 4607827 nano seconds
        Variant took 2628095 nano seconds

        This confuses me. It seems that Variant is quicker if you declare the variable inside the loop.

        Also the conclusion I draw from this is that performance impact of the conversion methods are largely negligible. And if your implementation requires that you use an definition with the .toString() conversion(Such as QString x = myVar.toString()), you are better off using QVariant.

        jsulmJ 1 Reply Last reply
        0
        • M Mike Fidel

          @jsulm This is the benchmark I did:

          int main(int argc, char *argv[])
          {
              QElapsedTimer variantTimer;
              QElapsedTimer stringTimer;
          
              QVariant var = QVariant("My String");
          
              QString string = "My String";
          
          
          
              QString stringTest;
              QString varTest;
          
          
              stringTimer.start();
              for (int i = 0 ; i < 100000 ; i++)
              {
                    stringTest = string;
              }
          
              std::cout << "string  took " << stringTimer.nsecsElapsed() << " nano seconds " << std::endl;
          
          
          
              variantTimer.start();
              for (int i = 0 ; i < 100000 ; i++)
              {
                  varTest = var.toString();
              }
          
              std::cout << "Variant took " << variantTimer.nsecsElapsed() << " nano seconds " << std::endl;
          
          
          }
          

          Output I got:

          string took 2084675 nano seconds
          Variant took 4343839 nano seconds

          However if you include the deceleration of QString inside the loop like so:

          int main(int argc, char *argv[])
          {
              QElapsedTimer variantTimer;
              QElapsedTimer stringTimer;
          
              QVariant var = QVariant("My String");
          
              QString string = "My String";
          
          
          
              //QString stringTest;
              //QString varTest;
          
          
              stringTimer.start();
              for (int i = 0 ; i < 100000 ; i++)
              {
                    QString stringTest = string;
              }
          
              std::cout << "string  took " << stringTimer.nsecsElapsed() << " nano seconds " << std::endl;
          
          
          
              variantTimer.start();
              for (int i = 0 ; i < 100000 ; i++)
              {
                  QString varTest = var.toString();
              }
          
              std::cout << "Variant took " << variantTimer.nsecsElapsed() << " nano seconds " << std::endl;
          
          
          }
          
          
          

          I get the following output:

          string took 4607827 nano seconds
          Variant took 2628095 nano seconds

          This confuses me. It seems that Variant is quicker if you declare the variable inside the loop.

          Also the conclusion I draw from this is that performance impact of the conversion methods are largely negligible. And if your implementation requires that you use an definition with the .toString() conversion(Such as QString x = myVar.toString()), you are better off using QVariant.

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

          @Mike-Fidel Probably I was wrong: QVariant already contains a QString

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

          M 1 Reply Last reply
          1
          • J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by J.Hilk
            #5

            Isn't QString and QVariant each Implicitly Shared ?

            that means

            for (int i = 0 ; i < 100000 ; i++)
                {
                      stringTest = string;
                }
            

            does basicaly nothing? Decrese and Increase of shared pointer count

            where as

             for (int i = 0 ; i < 100000 ; i++)
                {
                    varTest = var.toString();
                }
            

            is an actual convertion => Construction of a QString and copy of data(from Qvariant)?


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            5
            • jsulmJ jsulm

              @Mike-Fidel Probably I was wrong: QVariant already contains a QString

              M Offline
              M Offline
              Mike Fidel
              wrote on last edited by
              #6

              @jsulm said in QVariant conversions (.toString() .toInt()) performance.:

              @Mike-Fidel Probably I was wrong: QVariant already contains a QString

              So QVariant might be faster, but costs more memory?

              jsulmJ 1 Reply Last reply
              0
              • M Mike Fidel

                @jsulm said in QVariant conversions (.toString() .toInt()) performance.:

                @Mike-Fidel Probably I was wrong: QVariant already contains a QString

                So QVariant might be faster, but costs more memory?

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

                @Mike-Fidel It should not cost more memory because of implicit sharing as @J-Hilk mentioned.

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

                M 1 Reply Last reply
                0
                • jsulmJ jsulm

                  @Mike-Fidel It should not cost more memory because of implicit sharing as @J-Hilk mentioned.

                  M Offline
                  M Offline
                  Mike Fidel
                  wrote on last edited by
                  #8

                  @jsulm said in QVariant conversions (.toString() .toInt()) performance.:

                  @Mike-Fidel It should not cost more memory because of implicit sharing as @J-Hilk mentioned.

                  Could you elaborate? As far as I understand "Implicit Sharing" means that on assignment a pointer is passed, and only on write a copy occurs.

                  So in

                  for (int i = 0 ; i < 100000 ; i++)
                      {
                            stringTest = string;
                      }
                  

                  And in

                   for (int i = 0 ; i < 100000 ; i++)
                      {
                          varTest = var.toString();
                      }
                  

                  The memory fingerprint of 'varTest' and 'stringTest' should be the same. But you said that QVariant already contains a QString, shouldn't it take up more memory?

                  Also How does implicit sharing explains QVariant being faster when the deceleration is made inside the loop?

                  jsulmJ 1 Reply Last reply
                  0
                  • M Mike Fidel

                    @jsulm said in QVariant conversions (.toString() .toInt()) performance.:

                    @Mike-Fidel It should not cost more memory because of implicit sharing as @J-Hilk mentioned.

                    Could you elaborate? As far as I understand "Implicit Sharing" means that on assignment a pointer is passed, and only on write a copy occurs.

                    So in

                    for (int i = 0 ; i < 100000 ; i++)
                        {
                              stringTest = string;
                        }
                    

                    And in

                     for (int i = 0 ; i < 100000 ; i++)
                        {
                            varTest = var.toString();
                        }
                    

                    The memory fingerprint of 'varTest' and 'stringTest' should be the same. But you said that QVariant already contains a QString, shouldn't it take up more memory?

                    Also How does implicit sharing explains QVariant being faster when the deceleration is made inside the loop?

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

                    @Mike-Fidel QString uses implicit sharing as well. So, assigning a string to another one does not increase memory usage significantly.
                    Is it

                    QString varTest;
                    for (int i = 0 ; i < 100000 ; i++)
                    {
                        varTest = var.toString();
                    }
                    

                    or

                    for (int i = 0 ; i < 100000 ; i++)
                    {
                        QString varTest = var.toString();
                    }
                    

                    ?

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

                    M 1 Reply Last reply
                    0
                    • jsulmJ jsulm

                      @Mike-Fidel QString uses implicit sharing as well. So, assigning a string to another one does not increase memory usage significantly.
                      Is it

                      QString varTest;
                      for (int i = 0 ; i < 100000 ; i++)
                      {
                          varTest = var.toString();
                      }
                      

                      or

                      for (int i = 0 ; i < 100000 ; i++)
                      {
                          QString varTest = var.toString();
                      }
                      

                      ?

                      M Offline
                      M Offline
                      Mike Fidel
                      wrote on last edited by
                      #10

                      @jsulm

                      QString uses implicit sharing as well. So, assigning a string to another one does not increase memory usage significantly.

                      Yes I understand, However I'm confused by what you said that QVariant already contains QString. Because if it does, shouldn't it take up more memory than just QString ? Because QVaraint is QString and something else ?

                      JonBJ 1 Reply Last reply
                      0
                      • M Mike Fidel

                        @jsulm

                        QString uses implicit sharing as well. So, assigning a string to another one does not increase memory usage significantly.

                        Yes I understand, However I'm confused by what you said that QVariant already contains QString. Because if it does, shouldn't it take up more memory than just QString ? Because QVaraint is QString and something else ?

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

                        @Mike-Fidel
                        @jsulm did use the word "significantly". I don't know whether someone is saying the whole of a QVariant is shared or just its content, but if it's the latter, yes, a QVaraint is a QString and something else, but the "something else" is relatively small, at least compared to, say, an "average" 42-byte string.

                        M 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @Mike-Fidel
                          @jsulm did use the word "significantly". I don't know whether someone is saying the whole of a QVariant is shared or just its content, but if it's the latter, yes, a QVaraint is a QString and something else, but the "something else" is relatively small, at least compared to, say, an "average" 42-byte string.

                          M Offline
                          M Offline
                          Mike Fidel
                          wrote on last edited by
                          #12

                          @JonB Got it, Thanks!

                          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
                          • Unsolved