question for #define experts - page 7

 
Alexandr Andreev:

You have not mixed up anything in your code, who is going to change the value for you?

as it does in the first version.

Yes, missed that point. Corrected my post.

 
Valeriy Yastremskiy:

There's a random result there. Compilation unfolds access to a memory cell with an array size value, and the array size will be obtained and placed in the memory cell in advance, when the array is formed, even if the array is dynamic, and cells with an array size and with a variable value will have the same access time.

And judging by the phrase that compilers do in the 3-4 year computer science course ... in general, I will hope that a sufficiently adequate level of personnel will not make me very nervous in the MCL environment)

Believe me the average student usually FIVT is just zero with plus), since there is zero experience, and knowledge without experience quickly goes nowhere (forgotten), and their examples are very strange, it will take years before the student understands where and how they can be used. This is if you compare it with an experienced programmer.

 
Alexandr Andreev:

Believe me, the average FIVT student is usually a zero plus), because there is zero experience, and knowledge without experience quickly goes nowhere (is forgotten), and their examples are very strange, it will take years before the student understands where and how they can be used. This is if you compare it with an experienced programmer.

It's understandable. I don't understand why you have to teach how to make a compiler. It's like teaching how to create one's own language. It's clear that a language is a class, but not every bird can fly a priori. Well, as I have already mentioned above, Errors, Bugs, Questions are also relevant to the question of optimizing the compilation on the fly.

 

The topic is about defines, not loops ))

But I still don't understand, is there sense in defining code, for example, user-defined functions.
In the hope that defunct code will be executed faster in the executable file.
Or is it a misunderstanding? Because substitution is only a pre-compilation action, and it makes sense only to speed up build.

 
Roman:

The topic is about defines, not loops ))

But I still don't understand, is there sense in defining code, for example, user-defined functions.
In the hope that defunct code will be executed faster in the executable file.
Or is it a misunderstanding? Because substitution is only a pre-compilation action, and it is only logical to speed up build.

I just showed you an example where 3 external functions are used... against its unfolded form. So there will be no acceleration.

Forum on trading, automated trading systems and strategy testing

Question for #define experts

Alexandr Andreev, 2020.11.02 19:49

void OnStart()
  {
   int mas[];
   int size=1000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100;
   uint t1=GetTickCount();
   int t=0;
   int tr=0; 
   MathSrand(10);
   for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); Funk(i))
        { 
         FunkRand(r1); 
         Funk(r);// мы сюда написали вызов еще одной функции чтобы усложить ситуацию
        }
     }
   tr=r;
   uint t2=GetTickCount();
   for(ulong z=0; z<max; z++)
     {
     int v=size;
      for(ulong i=0; i<v; i++)
        { 
         r2+=rand();
         r--;
        }

     }

   uint t3=GetTickCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",t1," ",tr);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

500p question (without checking) which way is faster. see how many external functions are called in the upper method


Документация по MQL5: Основы языка / Функции / Описание внешних функций
Документация по MQL5: Основы языка / Функции / Описание внешних функций
  • www.mql5.com
Внешние функции, определенные в другом модуле, должны быть явно описаны. Описание включает в себя тип возвращаемого значения, имя функции и набор входных параметров с их типами. Отсутствие такого описания может привести к ошибкам при компиляции, компоновке или выполнении программы. При описании внешнего объекта используйте ключевое слово С...
 
Alexandr Andreev:

I gave you an example where 3 external functions are used... against its unfolded form. So there will be no acceleration.


I see. Then hello to fxsaber. A guy who likes to defund everything.


Alexandr Andreev:

Prove me wrong)

because in my test they are the same for some reason.

As for ArraySize() and variable. Still I will return to this question.
Here's what I've changed in the test. The loop counts the number of PI.
In the first sample, the loop's condition uses ArraySize().
In the second example, the variable num_steps is used.
There is a difference.

ArraySize() function

void OnStart()
{
    int arr[];
    int num_steps = ArrayResize(arr, 1000000000);

    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
    ulong t = GetMicrosecondCount();
    
    for (int i = 0; i<ArraySize(arr); i++)
    {
       x = (i + .5) * step;
       sum = sum + 4.0 / (1.0 + x * x);
    }
    
    pi = sum*step;
        
    t = GetMicrosecondCount() - t;
   
   printf("The value of PI is %1.12f ", pi);
   PrintFormat("Total time to calculate PI was %5.3f ms\n", t / 1000.0);
}

Three runs of the script.

2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  Total time to calculate PI was 4049.179 ms
2020.11.02 23:56:51.556 TestScript (USDJPY,M1)  
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  Total time to calculate PI was 4183.364 ms
2020.11.02 23:56:57.928 TestScript (USDJPY,M1)  
2020.11.02 23:57:03.884 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.02 23:57:03.884 TestScript (USDJPY,M1)  Total time to calculate PI was 4034.098 ms
        


Variable num_steps.

void OnStart()
{
    int arr[];
    int num_steps = ArrayResize(arr, 1000000000);

    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
    ulong t = GetMicrosecondCount();
    
    for (int i = 0; i<num_steps; i++)
    {
        x = (i + .5) * step;
        sum = sum + 4.0 / (1.0 + x * x);
    }
    
    pi = sum*step;
        
    t = GetMicrosecondCount() - t;
   
   printf("The value of PI is %1.12f ", pi);
   PrintFormat("Total time to calculate PI was %5.3f ms\n", t / 1000.0);
}

Three runs of the script.

2020.11.03 00:08:09.269 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:09.271 TestScript (USDJPY,M1)  Total time to calculate PI was 3955.325 ms
2020.11.03 00:08:09.271 TestScript (USDJPY,M1)  
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  Total time to calculate PI was 3950.568 ms
2020.11.03 00:08:15.578 TestScript (USDJPY,M1)  
2020.11.03 00:08:22.469 TestScript (USDJPY,M1)  The value of PI is 3.141592653590 
2020.11.03 00:08:22.469 TestScript (USDJPY,M1)  Total time to calculate PI was 3927.110 ms
        
 
Roman:

I see. Then hello to fxsaber. A fan of defining everything in a row.

As for ArraySize() and the variable. I'll get back to this question all the same.
Here's the test I modified. The loop counts the number of PI.
In the first sample, the loop's condition usesArraySize().
In the second example, the variable
num_steps is used.
There is a difference.

ArraySize() function

Three runs of the script.


Variable num_steps.

Three runs of the script.

Not a clear difference in these calculations. I put all this in one code and the results are different, there is one where the first variant wins

)) any array in µl has a variable which is responsible for the current size of the array, so in most languages.

The ArraySize function tells the compiler to return the value of this variable, i.e., it substitutes this variable instead of this function. Since µl arrays cannot be referenced, the pointer is explicitly to this variable, right to the crocette address in memory. Technically, all these tests are an attempt to compare two regular variables. This is the property of unfolding functions, in my example 4 functions forgive 0 functions, 3 of which are right in the loop body i.e. there is a comparison of 40000000000 function calls vs none. And we see an implicit difference that is too small to notice - because it's putting code in the executable file.... we're comparing the same thing.

And all these calculations - the more complicated they are, the less sense they make.

It is easier to give an example where in one case we call a hundred functions, functions within functions... And in the other case, all this in expanded form - and there will be no difference. Since ArraySize(mas)== mas[].size

Документация по MQL5: Операции с массивами / ArraySize
Документация по MQL5: Операции с массивами / ArraySize
  • www.mql5.com
"Нулевое измерение = Размер массива / (Первое измерение * Второе измерение * Третье измерение)"
 

Although for some reason the pi example does have a difference ..... by overshoot frequency, (redaction) although this is purely random overshoot

and it is equal to 1ms per 1 billion outputs, although this is not explicitly tried comparing variable with variable and the spread became even larger)))


 
Alexandr Andreev:

Not a clear difference with these calculations. Put it all in one code, and the results are different, there are some where the first option wins

)) Every array in µl has a variable responsible for the current array size, so in most languages.

The ArraySize function tells the compiler to return the value of this variable, i.e., it substitutes this variable instead of this function. Since µl arrays cannot be referenced, the pointer is explicitly to this variable, right to the crocette address in memory. Technically, all these tests are an attempt to compare two regular variables. This is the property of unfolding functions, in my example 4 functions forgive 0 functions, 3 of which are right in the loop body i.e. there is a comparison of 40000000000 function calls vs none. And we see an implicit difference that is too small to notice - because it's putting code in the executable file.... we're comparing the same thing.

And all these calculations - the more complicated they are, the less sense they make.

It's easier to give an example where in one case we call a hundred functions, functions within functions... And in the other case, all this in expanded form - and there will be no difference. Since ArraySize(mas)== mas[].size

It does not matter what is executed in the loop body. This is just a load for the test.
The examples compare reference to a function or variable in the loop condition.

I'm not an assembler, but I think it's not the same thing from the viewpoint of assembler instructions.
And if it's also wrapped in a class, it's certainly not the same thing.

A function has an extra instruction to retrieve a value from a memory cell, i.e. the function calls the memory cell for a value and only then returns the result.
A variable already has this value; the variable doesn't reference anything; it returns the result immediately.

 
Roman:

It doesn't matter what is performed in the body of the cycle. It's just a load for the test.
The examples compare the reference to a function or variable in the loop condition.

I'm no expert in assembler, but I think from the point of view of assembly instructions, it's not the same thing.
And if it's also wrapped in a class, it's certainly not the same thing.

A function has an extra instruction to retrieve a value from a memory cell, i.e. the function calls the memory cell for a value and only then returns the result.
A variable already has that value, the variable doesn't reference anywhere, it returns the result immediately.

) Well, that's not how it works)

 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   int mas[];
   int mas1[300];
   int mas2[300];
   int mas3[300];
   int mas4[300];
   int mas5[300];
   int mas6[300];
   int z=300;
   int size=100000000;
   ArrayResize(mas,size);
   ulong r=0;
   ulong r1=0;
   ulong r2=0;
   int random;
   ulong max=100; 
   int t=0;
   int tr=0; 
   MathSrand(10);
    int num_steps=ArraySize(mas);
    double x, pi, sum=0.0;
    double step = 1.0/(double)num_steps;
    
     int v=size;
    ulong t1 = GetMicrosecondCount();
     
    
  // for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<ArraySize(mas); i++)
        { 
        r2+=ArraySize(mas);
        r2+=ArraySize(mas1);
        r2+=ArraySize(mas2);
        r2+=ArraySize(mas3);
        r2+=ArraySize(mas4);
        r2+=ArraySize(mas5);
        r2+=ArraySize(mas6);
        r2+=ArraySize(mas1);
        r2+=ArraySize(mas2);
        r2+=ArraySize(mas3);
        r2+=ArraySize(mas4);
        r2+=ArraySize(mas5);
        r2+=ArraySize(mas6);
        r2+=ArraySize(mas1);
        r2=r2/10;
        }

     }  
   ulong t2=GetMicrosecondCount();
   //for(ulong z=0; z<max; z++)
     {
      for(ulong i=0; i<v; i++)
        { 
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1+=z;
        r1=r1/10;
        }
     }
   
   int pi2 = sum*step;
   ulong t3=GetMicrosecondCount();
   Print(t2-t1,"  ",t3-t2," ",r," ",r1," ",r2," ",pi," ",pi2);
// Templ();
  }

//+------------------------------------------------------------------+
//|                                           
  
void Funk(ulong &a){a++;}
void FunkRand(ulong &a){a+=rand();}

//+------------------------------------------------------------------+

Almost every run the leader changes

the longest one is division)))