Declaring variables behind the loop or inside the loop? - page 4

 

Sorry folks, optimisation has been switched off in the project settings

Code:

   CStopWatch sw; // Секундомер, для замера времени
   
   sw.Start();
   for (int i = 0; i < 10000000; i++)
   {
      string st = (string)i;
   }
   pr("Test1, время выполнения: " + sw.Stop());

   sw.Start();
   string st = "";
   for (int i = 0; i < 10000000; i++)
   {
      st = (string)i;
   }
   pr("Test2, Время выполнения: " + sw.Stop());


Unoptimised

Test1, время выполнения: 0.548275 сек.
Test2, Время выполнения: 0.313978 сек.

With optimization

Test1, время выполнения: 0.420523 сек.
Test2, Время выполнения: 0.545999 сек.

With optimisation yes, it's the opposite, I've checked many times

 
Aleksandr Matveev:

You should learn the basics first and then prove your point. You would understand the result without any tests, if you had read at least one book on CPU and memory operation. I've offered you the most ingenious one and if you want to advance a bit in programming you're sure to read it.

What does memory and CPU have to do with it? It's about optimization, you bookish theorist).

 
Igor Makanu:

it's not strange, you need to be able to test the simplest operators and operations in MQL - why would I add srand(GetTickCount()) to my test? ?

;)

By the way, look closely, the result in your loop is not taken into account in any way, which means that it can be easily cut out by the compiler.

 
Alexey Navoykov:

By the way, I looked closely, the result in your loop is not taken into account in any way, so the compiler can easily cut it out.

Removed even rand() - its compiler inlines it perfectly, made such a test:

#define  N 8

#define    test(M,S,EX) {                                 \
uint mss=GetTickCount();                                 \
ulong nn=(ulong)pow(10,M);                               \
for(ulong tst=0;tst<nn && !_StopFlag;tst++) \
{ EX; }                                                  \
printf("%s: loops=%i ms=%u",S,nn,GetTickCount()-mss);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   string s1;  test(N,"1. s1=rand()",s1=(string)tst);
   string s2;  test(N,"2. s2=rand()",s2=(string)tst);
   string s3;  test(N,"3. s3=rand()",s3=(string)tst);
   string s4;  test(N,"4. s4=rand()",s4=(string)tst);
   string s5;  test(N,"5. s5=rand()",s5=(string)tst);

   test(N,"1. q=rand()",string q=(string)tst);
   test(N,"2. q=rand()",string q=(string)tst);
   test(N,"3. q=rand()",string q=(string)tst);
   test(N,"4. q=rand()",string q=(string)tst);
   test(N,"5. q=rand()",string q=(string)tst);
  }
//+------------------------------------------------------------------+

2019.08.18 11:55:41.457 SpeedTest (EURUSD,H1) 1. s1=rand(): loops=100000000 ms=7672

2019.08.18 11:55:49.085 SpeedTest (EURUSD,H1) 2. s2=rand(): loops=100000000 ms=7625

2019.08.18 11:55:56.796 SpeedTest (EURUSD,H1) 3. s3=rand(): loops=100000000 ms=7719

2019.08.18 11:56:04.495 SpeedTest (EURUSD,H1) 4. s4=rand(): loops=100000000 ms=7703

2019.08.18 11:56:12.113 SpeedTest (EURUSD,H1) 5. s5=rand(): loops=100000000 ms=7610

2019.08.18 11:56:17.695 SpeedTest (EURUSD,H1) 1. q=rand(): loops=100000000 ms=5578

2019.08.18 11:56:23.362 SpeedTest (EURUSD,H1) 2. q=rand(): loops=100000000 ms=5672

2019.08.18 11:56:28.970 SpeedTest (EURUSD,H1) 3. q=rand(): loops=100000000 ms=5609

2019.08.18 11:56:34.637 SpeedTest (EURUSD,H1) 4. q=rand(): loops=100000000 ms=5672

2019.08.18 11:56:40.277 SpeedTest (EURUSD,H1) 5. q=rand(): loops=100000000 ms=5640


 
Alexey Navoykov:

So I'm saying, if you want to "do it right", then go to assembler. If you need to control everything yourself... After all, the case you just described is nothing at all. There are far more complicated things. OOP is definitely contraindicated for you. You won't know whether or not the compiler has degenerated a particular virtual method into a regular call or trimmed an unnecessary pointer check... What can you do in a managed MQL with such paranoia? )

And to tweak code to the peculiarities of the compiler (and imaginary ones at that), to the detriment of code correctness and reliability, is obviously not what a good programmer should do. And here we are talking about code incorrectness. Variable must be declared directly in the block in which it is used.

Ha ha ha... Alexey, you claim (let's be "you") that "OOP is definitely contraindicated" to one of the main OOP adepts on the forum.

The code should not be adjusted to the peculiarities of the compiler, but to the peculiarities of OWN thinking. In this case, declaration of a variable inside a loop in theory reduces efficiency. Because according to the conventions, the variable must be created each time and destroyed each time.

It's not even the question of efficiency. Solid code is code, which is transparent, clear and easy to modify and maintain.

Personally I don't like having a lot of variables scattered all over the program and having to search for each time where a particular variable is created. Therefore, if possible, I try to declare variables at the beginning of the function, all together - just to see where they are created and understand when they will be deleted.

In this case, the example is just very short. When there are dozens of lines between creating a variable and using it, and a bunch of nested functions - to me, it's much more reliable when the variable is declared outside the block, in advance.

 
pivalexander:

Sorry folks, optimisation has been switched off in the project settings

Code:


Unoptimised

With optimisation

With optimization, yes, it's the opposite, I've checked it many times.

In your example, the whole loop body could have been cut out with optimization.

 

In general, it all comes together as expected, that there is no need to do nonsense, looking for non-existent problems and creating real ones.

If you're itchy and think you're a cool hacker, write in assembler, or else stand aside and let the compiler do its job.

 
Aleksandr Matveev:

In this example, your whole loop body could have been cut out using optimisation.

The result of executing with an empty loop body, very different, works much faster

Без оптимизации:
Test1, время выполнения: 0.027539 сек.

С оптимизацией:
Test1, время выполнения: 0.005448 сек.
 
Alexey Navoykov:

In general, it all comes together as expected, that there is no need to do nonsense, looking for non-existent problems and creating real ones.

If you're itchy and think you're a cool hacker, write in assembler, otherwise just stand aside and let the compiler do its job.

The main problem is precisely that I don't consider myself a coolhacker. This is why variables, in my opinion, should be declared outside the loop. And better - at the beginning of the function, all at once.

And just koolhousers can declare variables as needed, inside the code.

 
Georgiy Merts:

The main problem is precisely that I don't consider myself a coolhacker. That's why variables, in my opinion, should be declared outside the loop. And preferably at the beginning of the function, all at once.

Koolhackers can declare variables as needed within code.

I prefer to break my code into logical blocks and declare variables needed for them in those blocks rather than create a bunch of variables at the beginning of a function, most of which are only needed in one block, somewhere far below