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

 
pivalexander:

I prefer to divide the code into logical blocks and declare the variables needed for them in them, rather than creating a bunch of variables at the beginning of a function, most of which are only needed in one block, somewhere far down there

For variables needed in only one place - yes, it makes sense to declare them before the block itself, especially when the block is small. But, if block is big enough and variables are needed somewhere else - I would prefer to declare them at the beginning of the function. You have to use common sense here, though.

 
pivalexander:

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

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

What do you measure in microseconds? .... Are you sure you have a realistic test?

;)

Here's another test like this:

#define  N 8

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

   test(N,"1. q=",string q=(string)tst, result = q;);
   test(N,"2. w=",string w=(string)tst, result = w;);
   test(N,"3. e=",string e=(string)tst, result = e;);
   test(N,"4. r=",string r=(string)tst, result = r;);
   test(N,"5. t=",string t=(string)tst, result = t;);
  }

2019.08.18 12:14:20.765 SpeedTest (EURUSD,H1) 1. s1=: loops=100000000 ms=8156

2019.08.18 12:14:29.127 SpeedTest (EURUSD,H1) 2. s2=: loops=100000000 ms=8359

2019.08.18 12:14:37.353 SpeedTest (EURUSD,H1) 3. s3=: loops=100000000 ms=8235

2019.08.18 12:14:45.464 SpeedTest (EURUSD,H1) 4. s4=: loops=100000000 ms=8109

2019.08.18 12:14:53.557 SpeedTest (EURUSD,H1) 5. s5=: loops=100000000 ms=8094

2019.08.18 12:15:01.446 SpeedTest (EURUSD,H1) 1. q=: loops=100000000 ms=7890

2019.08.18 12:15:09.159 SpeedTest (EURUSD,H1) 2. w=: loops=100000000 ms=7703

2019.08.18 12:15:16.903 SpeedTest (EURUSD,H1) 3. e=: loops=100000000 ms=7750

2019.08.18 12:15:24.716 SpeedTest (EURUSD,H1) 4. r=: loops=100000000 ms=7813

2019.08.18 12:15:32.661 SpeedTest (EURUSD,H1) 5. t=: loops=100000000 ms=7937

 
Igor Makanu:

What do you measure in microseconds? .... Are you sure your test corresponds to reality?

   ulong  time_finish = GetMicrosecondCount();
   ulong  res = time_finish - time_start;

That's how I measure it.

 
pivalexander:

I'm measuring this way.

I understand that, but you have to measure at least a few seconds

Windows is not a real time system, is it? And the background tasks also require resources from Windows, so your tests are at the level of inaccuracy of the system timer and the background processes

imho, a test of at least 5 seconds is at least some reliable information

 
Igor Makanu:

I understand that, but you need to measure at least a few seconds

Windows is not a real time system, is it? And the background tasks also require resources from Windows, so your tests are at the level of inaccuracy of the system timer and the background processes

imho, a test of at least 5 seconds is at least some credible info

I measured several seconds each, the result is the same, why wait so long to post the result here

 

In general I decided to make a test, but 100% correct, so that nothing was cut out.

void OnStart()
{
  int count= (int)10 e6;

  { 
    uint t= GetTickCount();
    int sum=0;
        
    for (int i=0; i<count; i++)
    {
       string st = (string)i;
       sum += st[rand()%10];
    }
    Print("Test1, время выполнения: ", GetTickCount()-t," ms,  sum=",sum);
  }
  
  {
    uint t = GetTickCount();
    int sum=0;
    string st = "";
    for (int i=0; i<count; i++)
    {
       st = (string)i;
       sum += st[rand()%10];
    }
    Print("Test2, время выполнения: ", GetTickCount()-t," ms,  sum=",sum);
  }
}

In non-optimized mode the second variant indeed turns out to be faster, while in optimized mode it is vice versa. The second variant, meanwhile, somehow becomes slower than it was before optimization)

 
pivalexander:

Did measurements for a few seconds at a time, the result is the same, why wait long to post the result here

and several times the same test must be run, because there is a high probability of caching operations in the next test to get, that may come out that 2 identical tests with small differences will be performed differently - you do not see the difference of the same test?

It's up to you, as I wrote above, I don't trust anyone, even Windows, the processor and myself ;)


Alexey Navoykov:

In general I decided to make a test, but 100% correct, that nothing was cut out.

While in non-optimized mode the second variant is indeed faster, in optimized mode it is vice versa. And the second way, for some reason, becomes slower than before optimization)

It's not a fact, there is no srand() , I told you that rand() is very cool optimized by the compiler ;)

And copy the script text at least 2 times - so that you can see what the compiler has ripped off ;)

 
pivalexander:

What do memory and processor have to do with it? It's about optimization, you're a bookish theorist)

If you go further than the brackets in your reasoning and understand how a compiler works and how its optimization works, you'll see that any compiler's aim is to reduce the number of code execution clock cycles and reduce nonsequential memory accesses as much as possible. Correspondingly, the result of optimization of any compiler, if it exists, will be known to you in advance without any dumb tests. It's like using tests to figure out that 2 + 2 = 4...

And about the book theorist... This theorist has been writing since 87, starting with EC1020 and ZX Spectrum, wrote more than one compiler and hired more than 600 programmers to his company...

 
Aleksandr Matveev:

If you go further than the brackets in your reasoning and understand how the compiler works and how its optimization works, you'll see that any compiler's aim is to reduce the number of code execution clock cycles and reduce nonsequential memory accesses as much as possible and, consequently, the result of any compiler's optimization, if there is one, will be known to you beforehand without any dumb tests. It's like using tests to figure out that 2 + 2 = 4...

And about the book theorist... This theorist has been working since 87 when he started working with EU1020 and ZX Spectrum, wrote several compilers of his own and invited more than 600 programmers to his company...

You are busy with books, praising yourselves, but they didn't say anything about the essence of the issue, just dancing around the theory... If you read this you'll understand it... Memory and CPU, CPU and memory, more about the power supply, it's used there too ...

 
Did you know that a string can have a small internal buffer and for small strings, the data can go there in its entirety? So to say, to speed up most trivial cases. While fiddling with malloc() catching, I noticed that if string is shorter than about 15 characters, malloc doesn't fidget at all. How would your tests ...
Reason: