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.5k 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.
  • 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 Online
                Chris KawaC Online
                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 Online
                    Chris KawaC Online
                    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 Online
                        Chris KawaC Online
                        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