Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Simple big-looped program break down
Forum Updated to NodeBB v4.3 + New Features

Simple big-looped program break down

Scheduled Pinned Locked Moved Solved C++ Gurus
big loopbreak down
38 Posts 6 Posters 7.1k 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.
  • JonBJ JonB

    @J-Hilk
    Noooooo!!!

    xor eax, eax
    ret
    

    Those two lines just load eax with 0 (quicker than literal "load with 0") and return it as result --- it's an implicit return 0 at the end of main()!

    Believe me, somewhere there above it is the code for the loop :) Otherwise, if the compiler has really decided there are no side-effects because pa is never referenced so it will go on strike and do nothing, put a return pa[10] or something after your loop.

    J.HilkJ Offline
    J.HilkJ Offline
    J.Hilk
    Moderators
    wrote on last edited by
    #18

    @JonB actually, when I change the compiler to MSVC, the loop will never be removed, even with O3
    🤨 Windows, am I right!?

    3008d077-5095-470a-9108-694d50c8f8bc-image.png


    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.

    JonBJ 1 Reply Last reply
    0
    • J.HilkJ J.Hilk

      @JonB actually, when I change the compiler to MSVC, the loop will never be removed, even with O3
      🤨 Windows, am I right!?

      3008d077-5095-470a-9108-694d50c8f8bc-image.png

      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by JonB
      #19

      @J-Hilk
      Yep, that's more like it, good old MSVC! As I said, retry gcc with return pa[10] after the loop and then see?

      J.HilkJ 1 Reply Last reply
      0
      • JonBJ JonB

        @J-Hilk
        Yep, that's more like it, good old MSVC! As I said, retry gcc with return pa[10] after the loop and then see?

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by J.Hilk
        #20

        @JonB said in Simple big-looped program break down:

        return pa[10]

        you're right by returning pa[10] from main, the release timings look much more like I would have expected:

        211 84 52 52


        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
        1
        • JonBJ JonB

          @Please_Help_me_D
          For arrays: in the C family of languages, and most "general" programming languages, arrays are passed by reference, not by value.

          This if you declare a simple int fred and pass to a function func(int param), the value in fred is copied into param (and changing it inside the function has no effect on the caller's fred).

          OTOH, if you declare an array int fred[3] and pass to a function func(int *param) the array is passed by reference/pointer, i.e. C passes the address of the start of the array (and changing values at *param or param[2] does change what is in the fred array back in the caller). The obvious reason is that arrays can be large, so you don't want to have to copy them unless you have to.

          So in your example, when you pass your array (int[3]) to another function it does not "take twice the space in RAM". The only thing that takes more space is the pointer to the array in the receiving function, which is a fixed 4 or 8 bytes (32-/64-bit) regardless of whether the array itself occupies 400MB of RAM.

          Meanwhile, going back to your timings. I am surprised if the time to fill your QVector is as large as 10 seconds. I don't do C++ so I can't check. I was going to suggest trying a.resize() or a.reserve() before the loop, but I think the constructor has already done that. One possibility is that (I believe) QVector will do bounds checking each time on your a[i], which the pure C++ example above it will not do, and that will cost some. Instead of indexing by i, try using https://doc.qt.io/qt-5/qvector.html#begin etc. to do the fill via iterators and see if that is quicker? The other possibility is that QVector data is implicitly shared (https://doc.qt.io/qt-5/implicit-sharing.html). The Qt experts here may be able to indicate whether by changing its content in a loop there is an overhead in dealing with the shared storage area, I don't know.

          Please_Help_me_DP Offline
          Please_Help_me_DP Offline
          Please_Help_me_D
          wrote on last edited by
          #21

          @JonB I'm trying to understand how to adjust QVectror::iterator to assign values to an array. I did the following:

              QVector<int> a = {10, 20, 30, 40, 50};
              QVector<int>::iterator it = a.begin();
          
              clock_t start_time =  clock();
              while (it != a.end())
              {
                  cout << *it << endl;
                  it++;
              }
          

          but that just showed me what is the iterator. How to modify the code to fill an empty QVector with numbers?

          JonBJ 1 Reply Last reply
          0
          • Please_Help_me_DP Please_Help_me_D

            @JonB I'm trying to understand how to adjust QVectror::iterator to assign values to an array. I did the following:

                QVector<int> a = {10, 20, 30, 40, 50};
                QVector<int>::iterator it = a.begin();
            
                clock_t start_time =  clock();
                while (it != a.end())
                {
                    cout << *it << endl;
                    it++;
                }
            

            but that just showed me what is the iterator. How to modify the code to fill an empty QVector with numbers?

            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by
            #22

            @Please_Help_me_D said in Simple big-looped program break down:

                int i = 0;
                while (it != a.end())
                {
                    *it = i++;
                    it++;
                }
            
            
            Please_Help_me_DP 1 Reply Last reply
            2
            • JonBJ JonB

              @Please_Help_me_D said in Simple big-looped program break down:

                  int i = 0;
                  while (it != a.end())
                  {
                      *it = i++;
                      it++;
                  }
              
              
              Please_Help_me_DP Offline
              Please_Help_me_DP Offline
              Please_Help_me_D
              wrote on last edited by
              #23

              @JonB So the execution time for the code:

                  QVector<int> a(100000000);
                  QVector<int>::iterator it = a.begin();
                  int i = 0;
              
                  clock_t start_time =  clock(); // начальное время
                  while (it != a.end())
                  {
                      *it = i++;
                      it++;
                  }
                  clock_t end_time = clock(); // конечное время
                  clock_t d_time = end_time - start_time;
                  cout << d_time << endl;
              

              is 8-9 seconds
              By the way, the same operation in Matlab with single (float) precision accuracy takes 0.3 seconds. That means that Matlab loops not so slow as I thought:

              // Matlab code
              a = single(zeros(100000000,1)); // preallocate the memory
              tic // start time
              for n = 1:100000000
                  a(n) = single(n); // assign avlue to each position
              end
              toc // end time
              
              J.HilkJ JonBJ 2 Replies Last reply
              0
              • Please_Help_me_DP Please_Help_me_D

                @JonB So the execution time for the code:

                    QVector<int> a(100000000);
                    QVector<int>::iterator it = a.begin();
                    int i = 0;
                
                    clock_t start_time =  clock(); // начальное время
                    while (it != a.end())
                    {
                        *it = i++;
                        it++;
                    }
                    clock_t end_time = clock(); // конечное время
                    clock_t d_time = end_time - start_time;
                    cout << d_time << endl;
                

                is 8-9 seconds
                By the way, the same operation in Matlab with single (float) precision accuracy takes 0.3 seconds. That means that Matlab loops not so slow as I thought:

                // Matlab code
                a = single(zeros(100000000,1)); // preallocate the memory
                tic // start time
                for n = 1:100000000
                    a(n) = single(n); // assign avlue to each position
                end
                toc // end time
                
                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #24

                @Please_Help_me_D
                If anything, than you should take away from my test, that there's a difference between release and debug builds in c++

                build and run your test in release, it will drop way below 1 sec


                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.

                Please_Help_me_DP 1 Reply Last reply
                3
                • Please_Help_me_DP Please_Help_me_D

                  @JonB So the execution time for the code:

                      QVector<int> a(100000000);
                      QVector<int>::iterator it = a.begin();
                      int i = 0;
                  
                      clock_t start_time =  clock(); // начальное время
                      while (it != a.end())
                      {
                          *it = i++;
                          it++;
                      }
                      clock_t end_time = clock(); // конечное время
                      clock_t d_time = end_time - start_time;
                      cout << d_time << endl;
                  

                  is 8-9 seconds
                  By the way, the same operation in Matlab with single (float) precision accuracy takes 0.3 seconds. That means that Matlab loops not so slow as I thought:

                  // Matlab code
                  a = single(zeros(100000000,1)); // preallocate the memory
                  tic // start time
                  for n = 1:100000000
                      a(n) = single(n); // assign avlue to each position
                  end
                  toc // end time
                  
                  JonBJ Online
                  JonBJ Online
                  JonB
                  wrote on last edited by JonB
                  #25

                  @Please_Help_me_D
                  Please do as @J-Hilk has said before, if you're compiling or running for debug there will be a vast difference from release/optimized

                  Also separately, verify what the MATLAB does in your code with

                  for n = 1:100000001

                  Please_Help_me_DP 1 Reply Last reply
                  2
                  • J.HilkJ J.Hilk

                    @Please_Help_me_D
                    If anything, than you should take away from my test, that there's a difference between release and debug builds in c++

                    build and run your test in release, it will drop way below 1 sec

                    Please_Help_me_DP Offline
                    Please_Help_me_DP Offline
                    Please_Help_me_D
                    wrote on last edited by
                    #26

                    @J-Hilk sorry I forgot that!

                        int *pa = new int [100000000];
                        clock_t start_time =  clock(); 
                        for (int i = 0; i < 100000000; i++)
                        {
                            pa[i] = i;
                        }
                        clock_t end_time = clock(); 
                        clock_t d_time = end_time - start_time;
                        cout << d_time << endl;
                    

                    is 0.14 second

                        QVector<int> a(100000000);
                    
                        clock_t start_time =  clock();
                        for (int i = 0; i < 100000000; i++)
                        {
                            a[i] = i;
                        }
                        clock_t end_time = clock(); 
                        clock_t d_time = end_time - start_time;
                        cout << d_time << endl;
                    

                    is also about 0.14 second

                        QVector<int> a(100000000);
                        QVector<int>::iterator it = a.begin(); /
                        int i = 0;
                    
                        clock_t start_time =  clock(); 
                        while (it != a.end())
                        {
                            *it = i++;
                            it++;
                        }
                        clock_t end_time = clock(); 
                        clock_t d_time = end_time - start_time; 
                        cout << d_time << endl;
                    

                    is also about 0.14 second
                    So Matlab loops is about twice slower :)
                    Thank you very much! It's good to know such difference in perfomance in Debug and Release mode

                    1 Reply Last reply
                    2
                    • JonBJ JonB

                      @Please_Help_me_D
                      Please do as @J-Hilk has said before, if you're compiling or running for debug there will be a vast difference from release/optimized

                      Also separately, verify what the MATLAB does in your code with

                      for n = 1:100000001

                      Please_Help_me_DP Offline
                      Please_Help_me_DP Offline
                      Please_Help_me_D
                      wrote on last edited by Please_Help_me_D
                      #27

                      @JonB Matlab automatically increases the vector size by 1. But if I dont preallocate the size of the vector and with each iteration the vector size increases then it takes way much time. Here I do the iteration without preallocation and variable "a" is created when first iteration is performed:

                      // Matlab code
                      tic
                      for n = 1:100000000
                             a(n) = single(n);
                      end
                      toc
                      

                      35 seconds to preform

                      JonBJ 1 Reply Last reply
                      0
                      • Please_Help_me_DP Please_Help_me_D

                        @JonB Matlab automatically increases the vector size by 1. But if I dont preallocate the size of the vector and with each iteration the vector size increases then it takes way much time. Here I do the iteration without preallocation and variable "a" is created when first iteration is performed:

                        // Matlab code
                        tic
                        for n = 1:100000000
                               a(n) = single(n);
                        end
                        toc
                        

                        35 seconds to preform

                        JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by JonB
                        #28

                        @Please_Help_me_D
                        For presumably similar slowness with QVector, try creating it empty with just QVector<int> a and use a.append(i) in the loop. I anticipate some slowness compared to pre-sizing, but (hopefully) not as bad as it could be:

                        This operation is relatively fast, because QVector typically allocates more memory than necessary, so it can grow without reallocating the entire vector each time.

                        Please_Help_me_DP 1 Reply Last reply
                        1
                        • JonBJ JonB

                          @Please_Help_me_D
                          For presumably similar slowness with QVector, try creating it empty with just QVector<int> a and use a.append(i) in the loop. I anticipate some slowness compared to pre-sizing, but (hopefully) not as bad as it could be:

                          This operation is relatively fast, because QVector typically allocates more memory than necessary, so it can grow without reallocating the entire vector each time.

                          Please_Help_me_DP Offline
                          Please_Help_me_DP Offline
                          Please_Help_me_D
                          wrote on last edited by
                          #29

                          @JonB very interesting result as for me:

                               QVector<int> a;
                          
                               clock_t start_time =  clock();
                               for (int i = 0; i < 100000000; i++)
                               {
                                   a.append(i);
                               }
                               clock_t end_time = clock();
                               clock_t d_time = end_time - start_time;
                               cout << d_time << endl;
                          

                          in Debug mode it takes 5.5-6 seconds
                          in Release mode it takes 0.7 second (while in Matlab as I previously said it takes 35 seconds)
                          So QVectror is really fast even if it works with <appending mode>
                          Thank you for this example!

                          jsulmJ 1 Reply Last reply
                          0
                          • Please_Help_me_DP Please_Help_me_D

                            @JonB very interesting result as for me:

                                 QVector<int> a;
                            
                                 clock_t start_time =  clock();
                                 for (int i = 0; i < 100000000; i++)
                                 {
                                     a.append(i);
                                 }
                                 clock_t end_time = clock();
                                 clock_t d_time = end_time - start_time;
                                 cout << d_time << endl;
                            

                            in Debug mode it takes 5.5-6 seconds
                            in Release mode it takes 0.7 second (while in Matlab as I previously said it takes 35 seconds)
                            So QVectror is really fast even if it works with <appending mode>
                            Thank you for this example!

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

                            @Please_Help_me_D said in Simple big-looped program break down:

                            So QVectror is really fast even if it works with <appending mode>

                            As far as I know QVector allocates more memory as currently is need and on resizing it allocates again more than "current_size + 1".

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

                            Please_Help_me_DP JonBJ 2 Replies Last reply
                            0
                            • jsulmJ jsulm

                              @Please_Help_me_D said in Simple big-looped program break down:

                              So QVectror is really fast even if it works with <appending mode>

                              As far as I know QVector allocates more memory as currently is need and on resizing it allocates again more than "current_size + 1".

                              Please_Help_me_DP Offline
                              Please_Help_me_DP Offline
                              Please_Help_me_D
                              wrote on last edited by
                              #31

                              @jsulm yes it does.
                              I tested how much my program weigh with Windows Task Manager for different number of loops (say n) and two mode of QVector (normal and <append>). Here is the result (Debug mode):

                                  QVector<int> a(100000000);
                              
                                  clock_t start_time =  clock();
                                  for (int i = 0; i < 100000000; i++)
                                  {
                                      a[i] = i;
                                  }
                                  clock_t end_time = clock();
                                  clock_t d_time = end_time - start_time; 
                                  cout << d_time << endl;
                              

                              n = 100000000 -> 392464 kilobytes
                              n = 100000000/2 -> 196780 kilobytes
                              n = 100000000/4 -> 98936 kilobytes
                              n = 100000000/8 -> 50008 kilobytes
                              !_____________________________!

                                   QVector<int> a;
                              
                                   clock_t start_time =  clock();
                                   for (int i = 0; i < 100000000; i++)
                                   {
                                       a.append(i);
                                   }
                                   clock_t end_time = clock(); 
                                   clock_t d_time = end_time - start_time; 
                                   cout << d_time << endl;
                              

                              n = 100000000 -> 527456 kilobytes
                              n = 100000000/2 -> 264804 kilobytes
                              n = 100000000/4 -> 133468 kilobytes
                              n = 100000000/8 -> 67804 kilobytes

                              If I use simple C++ array insead of QVector then for n = 100000000 -> 391780 kilobytes (almost the same as simple QVector).

                              So the conclusion I see is that QVector in <append> mode weighs 1.35 times simple QVector or C++ array

                              J.HilkJ 1 Reply Last reply
                              0
                              • Please_Help_me_DP Please_Help_me_D

                                @jsulm yes it does.
                                I tested how much my program weigh with Windows Task Manager for different number of loops (say n) and two mode of QVector (normal and <append>). Here is the result (Debug mode):

                                    QVector<int> a(100000000);
                                
                                    clock_t start_time =  clock();
                                    for (int i = 0; i < 100000000; i++)
                                    {
                                        a[i] = i;
                                    }
                                    clock_t end_time = clock();
                                    clock_t d_time = end_time - start_time; 
                                    cout << d_time << endl;
                                

                                n = 100000000 -> 392464 kilobytes
                                n = 100000000/2 -> 196780 kilobytes
                                n = 100000000/4 -> 98936 kilobytes
                                n = 100000000/8 -> 50008 kilobytes
                                !_____________________________!

                                     QVector<int> a;
                                
                                     clock_t start_time =  clock();
                                     for (int i = 0; i < 100000000; i++)
                                     {
                                         a.append(i);
                                     }
                                     clock_t end_time = clock(); 
                                     clock_t d_time = end_time - start_time; 
                                     cout << d_time << endl;
                                

                                n = 100000000 -> 527456 kilobytes
                                n = 100000000/2 -> 264804 kilobytes
                                n = 100000000/4 -> 133468 kilobytes
                                n = 100000000/8 -> 67804 kilobytes

                                If I use simple C++ array insead of QVector then for n = 100000000 -> 391780 kilobytes (almost the same as simple QVector).

                                So the conclusion I see is that QVector in <append> mode weighs 1.35 times simple QVector or C++ array

                                J.HilkJ Offline
                                J.HilkJ Offline
                                J.Hilk
                                Moderators
                                wrote on last edited by
                                #32

                                @Please_Help_me_D said in Simple big-looped program break down:

                                So the conclusion I see is that QVector in <append> mode weighs 1.35 times simple QVector or C++ array

                                IIRC, than its 1.5, same as std::vector


                                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
                                1
                                • jsulmJ jsulm

                                  @Please_Help_me_D said in Simple big-looped program break down:

                                  So QVectror is really fast even if it works with <appending mode>

                                  As far as I know QVector allocates more memory as currently is need and on resizing it allocates again more than "current_size + 1".

                                  JonBJ Online
                                  JonBJ Online
                                  JonB
                                  wrote on last edited by
                                  #33

                                  @jsulm said in Simple big-looped program break down:

                                  @Please_Help_me_D said in Simple big-looped program break down:

                                  So QVectror is really fast even if it works with <appending mode>

                                  As far as I know QVector allocates more memory as currently is need and on resizing it allocates again more than "current_size + 1".

                                  Which is why I originally quoted from https://doc.qt.io/qt-5/qvector.html#append:

                                  This operation is relatively fast, because QVector typically allocates more memory than necessary, so it can grow without reallocating the entire vector each time.

                                  As for the exact timing: if, say, it re-allocates by powers of 2, I make that something log2(100000000) == 27 reallocations? :)

                                  kshegunovK 1 Reply Last reply
                                  0
                                  • JonBJ JonB

                                    @jsulm said in Simple big-looped program break down:

                                    @Please_Help_me_D said in Simple big-looped program break down:

                                    So QVectror is really fast even if it works with <appending mode>

                                    As far as I know QVector allocates more memory as currently is need and on resizing it allocates again more than "current_size + 1".

                                    Which is why I originally quoted from https://doc.qt.io/qt-5/qvector.html#append:

                                    This operation is relatively fast, because QVector typically allocates more memory than necessary, so it can grow without reallocating the entire vector each time.

                                    As for the exact timing: if, say, it re-allocates by powers of 2, I make that something log2(100000000) == 27 reallocations? :)

                                    kshegunovK Offline
                                    kshegunovK Offline
                                    kshegunov
                                    Moderators
                                    wrote on last edited by
                                    #34

                                    @JonB said in Simple big-looped program break down:

                                    As for the exact timing: if, say, it re-allocates by powers of 2, I make that something log2(100000000) == 27 reallocations?

                                    It doesn't. If memory serves me it has a special progression for the first 128 elements or so, and after that it doubles its size on each realloc.

                                    Read and abide by the Qt Code of Conduct

                                    JonBJ 1 Reply Last reply
                                    1
                                    • kshegunovK kshegunov

                                      @JonB said in Simple big-looped program break down:

                                      As for the exact timing: if, say, it re-allocates by powers of 2, I make that something log2(100000000) == 27 reallocations?

                                      It doesn't. If memory serves me it has a special progression for the first 128 elements or so, and after that it doubles its size on each realloc.

                                      JonBJ Online
                                      JonBJ Online
                                      JonB
                                      wrote on last edited by JonB
                                      #35

                                      @kshegunov
                                      When I wrote this for a realloc() replacement/interface many years ago, I did it by increasing powers of 2 :-) Either way, the point is it's order log2(n)-ish,

                                      kshegunovK 1 Reply Last reply
                                      0
                                      • JonBJ JonB

                                        @kshegunov
                                        When I wrote this for a realloc() replacement/interface many years ago, I did it by increasing powers of 2 :-) Either way, the point is it's order log2(n)-ish,

                                        kshegunovK Offline
                                        kshegunovK Offline
                                        kshegunov
                                        Moderators
                                        wrote on last edited by
                                        #36

                                        You do know I'm old, so you mustn't trust me too much. I wouldn't do it by increasing powers of two anyway, more like a percent of the current size, otherwise you're overshooting the needed capacity most of the time.

                                        Read and abide by the Qt Code of Conduct

                                        JonBJ 1 Reply Last reply
                                        0
                                        • kshegunovK kshegunov

                                          You do know I'm old, so you mustn't trust me too much. I wouldn't do it by increasing powers of two anyway, more like a percent of the current size, otherwise you're overshooting the needed capacity most of the time.

                                          JonBJ Online
                                          JonBJ Online
                                          JonB
                                          wrote on last edited by JonB
                                          #37

                                          @kshegunov
                                          You wrote:

                                          and after that it [Qt] doubles its size on each realloc.

                                          I wrote

                                          I did it by increasing powers of 2

                                          Doesn't "doubling" mean "the next power of 2"? That's what I was trying to convey.

                                          2^n < x < 2^(n +1)
                                          =>
                                          2^(n + 1) < 2*x < 2^(n + 2)
                                          

                                          Right?

                                          kshegunovK 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