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. Qt (C++) - method argument optimization?
Forum Updated to NodeBB v4.3 + New Features

Qt (C++) - method argument optimization?

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 4 Posters 3.4k Views 2 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
    maximus
    wrote on last edited by maximus
    #1

    I'm going back on my code after starting reading a C++ Book (programming-principles-and-practice-using-cpp-2nd)

    My background is Java so I mostly never used const and reference passing (&) in my functions

    Is there any benefit of using it with Qt?
    For example, passing a QList<Object> to a method this way:

    My original way (by value) :
    void method (QList<Object> lstObject)

    Recommended way (const reference):
    void method (const QList<Object>& lstObject)

    Is it worth it to also do it with basic type like int, double) ?
    What about Signal & Slot?

    I wonder why the compiler doesn't do this stuff for us, detect if we modify the method argument and optimize accordingly. I find the syntax to be a bother and hard to read.
    Thank you!


    Free Indoor Cycling Software - https://maximumtrainer.com

    1 Reply Last reply
    0
    • raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      the most important advantage is simply performance.
      Since you pass a const-reference of a list it can be passed directly to the calling function. The const ensures that it is not altered by the callee.
      When you pass it by value the whole list needs to be copied before it is passed to the callee. Depending on the data type this can be a very fatal operation which slows down your application. For small lists with simply data-types you wont recognize a difference.
      But it's good practice to do so and a big advantage of C++ to give you more control of the memory.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #3

        No need to use references for basic types.
        A reference is besides the scene a pointer, since an int has the same size as a pointer there is no benefit to pass int by const reference (other basic types have similar size, so no need for references).
        For signals/slots same rules apply.

        The compiler does not do it for you because you could change the parameter in your function/method by MISTAKE. So, it is up to you to tell the compiler whether you're going to change the parameter (non const reference) or not. Usually you should know what you are doing and write the code accordingly.

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

        raven-worxR 1 Reply Last reply
        0
        • jsulmJ jsulm

          No need to use references for basic types.
          A reference is besides the scene a pointer, since an int has the same size as a pointer there is no benefit to pass int by const reference (other basic types have similar size, so no need for references).
          For signals/slots same rules apply.

          The compiler does not do it for you because you could change the parameter in your function/method by MISTAKE. So, it is up to you to tell the compiler whether you're going to change the parameter (non const reference) or not. Usually you should know what you are doing and write the code accordingly.

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by raven-worx
          #4

          @jsulm said:

          No need to use references for basic types.

          dangerous advice for a C++ beginner.
          Imagine a list with a few hundrets of thousands int values contained. All values need to be traversed and copied in memory. And this is sub-optimal when it can be avoided.

          I forgot to mention that many classes are implicitly shared in Qt. So like the QList for example.
          Nevertheless the const-reference way is the recommended one in all cases.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          jsulmJ 1 Reply Last reply
          0
          • raven-worxR raven-worx

            @jsulm said:

            No need to use references for basic types.

            dangerous advice for a C++ beginner.
            Imagine a list with a few hundrets of thousands int values contained. All values need to be traversed and copied in memory. And this is sub-optimal when it can be avoided.

            I forgot to mention that many classes are implicitly shared in Qt. So like the QList for example.
            Nevertheless the const-reference way is the recommended one in all cases.

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

            @raven-worx I was talking about basic types like int, double, char and so on not about complex types like lists.

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

            raven-worxR 1 Reply Last reply
            0
            • jsulmJ jsulm

              @raven-worx I was talking about basic types like int, double, char and so on not about complex types like lists.

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by
              #6

              ah k...got it after reading it a second time

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              0
              • M Offline
                M Offline
                maximus
                wrote on last edited by maximus
                #7

                Thanks for the tips guys,

                I will revisit my code and change to "const reference" where I don't modify the argument and the argument is something else than a basic type (int, double).

                I think jsulm meant basic type that are not in container, e.g (int and not QList<int>)
                Also what I meant for the compiler is to detect wheter we change the argument, if so, pass it by value. If not, pass it by reference. But of course C++ let you modify function argument, and this would not let you do that (not a bad thing IMO..)


                Free Indoor Cycling Software - https://maximumtrainer.com

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  maximus
                  wrote on last edited by maximus
                  #8

                  Let say I have a constructor with a "const QVector<int>& vecId"
                  My goal is that I can manipulate this list but not modify it. (read only).

                  So I assign this list to a local QList of this Object.

                  this.vecId = vecId;  // vecId is of type QVector<int> vecId2
                  
                  qDebug() << "THIS IS THE LENGTH BEFORE REMOVAL " << this->vecId .size();
                  this->vecId .removeAt(0);
                  qDebug() << "THIS IS THE LENGTH AFTER REMOVAL " << this->vecId .size();
                  

                  Here I can still modify the QList
                  Is there a way to optimize this code or am I forced to pass the whole list by value like I was doing before? Thanks

                  Interesting, maybe I don't need to do it


                  Free Indoor Cycling Software - https://maximumtrainer.com

                  1 Reply Last reply
                  0
                  • Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @maximus said:

                    I wonder why the compiler doesn't do this stuff for us, detect if we modify the method argument and optimize accordingly

                    Because it can't. You can pass that parameter into another function. It can get an address of it and modify that. It can const_cast the parameter. It can use a goto into a code that modifies it. It can do million other crazy stuff with it. Compiler can't make guesses. It simply needs to be perfectly deterministic. The only way this sort of automatic optimization was possible is if your whole program was a constexpr evaluated at compile time, but then there would be no point in optimizing it at all, and such program would be useless anyway.

                    Here I can still modify the QList

                    No. You can (and did) modify a copy of the list. The original is intact.

                    Interesting, maybe I don't need to do it

                    Implicit sharing is meant to help moving large structures around but it's not free! It is still a copy of the object. A copy constructor is called. An internal reference count is changed as an atomic operation. The data is not copied (initially) but still a lot is going on. A const reference is basically a pointer on the stack, or even in a cpu register, which is as close to "free" as you will get.

                    M 1 Reply Last reply
                    0
                    • Chris KawaC Chris Kawa

                      @maximus said:

                      I wonder why the compiler doesn't do this stuff for us, detect if we modify the method argument and optimize accordingly

                      Because it can't. You can pass that parameter into another function. It can get an address of it and modify that. It can const_cast the parameter. It can use a goto into a code that modifies it. It can do million other crazy stuff with it. Compiler can't make guesses. It simply needs to be perfectly deterministic. The only way this sort of automatic optimization was possible is if your whole program was a constexpr evaluated at compile time, but then there would be no point in optimizing it at all, and such program would be useless anyway.

                      Here I can still modify the QList

                      No. You can (and did) modify a copy of the list. The original is intact.

                      Interesting, maybe I don't need to do it

                      Implicit sharing is meant to help moving large structures around but it's not free! It is still a copy of the object. A copy constructor is called. An internal reference count is changed as an atomic operation. The data is not copied (initially) but still a lot is going on. A const reference is basically a pointer on the stack, or even in a cpu register, which is as close to "free" as you will get.

                      M Offline
                      M Offline
                      maximus
                      wrote on last edited by maximus
                      #10

                      @Chris-Kawa

                      I was thinking something like this method

                      void printString(QString s) {
                          qDebug() << s;
                      /*
                      The compiler could detect that nothing was assigned to "s" since it can read the whole function, so it replace the argument with const QString& s.  In other words, the value of "s" after function execution is the same value as before for any input possible.
                      */
                      }
                      

                      I will read more on C++. For now, I will only replace my getter functions and add const at the end of them. Hopefully I can get the benefit on implicit sharing without doing too much work.
                      I just find it a bit sad the learning curve of C++ compared with other languages. That's what you get for starting with an "easy" language that doesn't have pointers and do memory management for you I guess. Thanks!


                      Free Indoor Cycling Software - https://maximumtrainer.com

                      1 Reply Last reply
                      0
                      • Chris KawaC Offline
                        Chris KawaC Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        I was thinking something like this method

                        You're forgetting that in c++ you can overload operators.
                        The signature of << is QDebug & operator<<(const QString & s) and that to some extent helps.
                        But what if it was QDebug & operator<<(QString& s)? How would the compiler know then that operator<< does not modify s internally?

                        I said to some extent because the compiler is really fighting an uphill battle.
                        For example the first line in that operator method could be something like

                        QString& foo = const_cast<QString&>(s);
                        foo = "gotcha!";
                        

                        If you think a compiler can follow this then what if the implementation was in a different translation unit or even in a different library? Of course the example is contrived and plain silly, but none the less valid c++ that a compiler must deal with correctly and not optimize stuff away.

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          maximus
                          wrote on last edited by
                          #12

                          Thanks Kawa, that example made me understood the whole problem.
                          Since any method can modify it's argument in C++, we need to had const to explicitly state that it does not.
                          I just never use this C++ feature (passing by reference without const), so that's probably why it was not natural for me.
                          I will go back to the books! I just feel changing an argument is "wrong" and I use a return value to do it, old habits...


                          Free Indoor Cycling Software - https://maximumtrainer.com

                          1 Reply Last reply
                          0
                          • Chris KawaC Offline
                            Chris KawaC Offline
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            @maximus said:

                            I just feel changing an argument is "wrong" and I use a return value to do it, old habits

                            If possible you should definitely avoid non-const reference arguments. Returning a value instead of modifying an argument is actually a very good thing in many situations. The optimizer will like that a lot.

                            Since you're up to reading about c++ you might want to look up return value optimization.
                            The fastest way to copy is to avoid copying in the first place ;)

                            Happy coding.

                            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